mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
Doc and Error Message Improvements (#60726)
This commit is contained in:
parent
e8e1eb51a4
commit
3176232cb4
|
@ -23,6 +23,11 @@ const EdgeInsets _kBackgroundButtonPadding = EdgeInsets.symmetric(
|
|||
/// Takes in a text or an icon that fades out and in on touch. May optionally have a
|
||||
/// background.
|
||||
///
|
||||
/// The [padding] defaults to 16.0 pixels. When using a [CupertinoButton] within
|
||||
/// a fixed height parent, like a [CupertinoNavigationBar], a smaller, or even
|
||||
/// [EdgeInsets.zero], should be used to prevent clipping larger [child]
|
||||
/// widgets.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * <https://developer.apple.com/ios/human-interface-guidelines/controls/buttons/>
|
||||
|
|
|
@ -674,7 +674,8 @@ class ListTile extends StatelessWidget {
|
|||
///
|
||||
/// Typically a [Text] widget.
|
||||
///
|
||||
/// This should not wrap.
|
||||
/// This should not wrap. To enforce the single line limit, use
|
||||
/// [Text.maxLines].
|
||||
final Widget title;
|
||||
|
||||
/// Additional content displayed below the title.
|
||||
|
@ -684,7 +685,8 @@ class ListTile extends StatelessWidget {
|
|||
/// If [isThreeLine] is false, this should not wrap.
|
||||
///
|
||||
/// If [isThreeLine] is true, this should be configured to take a maximum of
|
||||
/// two lines.
|
||||
/// two lines. For example, you can use [Text.maxLines] to enforce the number
|
||||
/// of lines.
|
||||
final Widget subtitle;
|
||||
|
||||
/// A widget to display after the title.
|
||||
|
@ -705,6 +707,9 @@ class ListTile extends StatelessWidget {
|
|||
///
|
||||
/// If false, the list tile is treated as having one line if the subtitle is
|
||||
/// null and treated as having two lines if the subtitle is non-null.
|
||||
///
|
||||
/// When using a [Text] widget for [title] and [subtitle], you can enforce
|
||||
/// line limits using [Text.maxLines].
|
||||
final bool isThreeLine;
|
||||
|
||||
/// Whether this list tile is part of a vertically dense list.
|
||||
|
|
|
@ -36,6 +36,10 @@ export 'package:flutter/services.dart' show SmartQuotesType, SmartDashesType;
|
|||
/// Remember to [dispose] of the [TextEditingController] when it is no longer needed.
|
||||
/// This will ensure we discard any resources used by the object.
|
||||
///
|
||||
/// By default, [TextFormField.decoration] will apply the
|
||||
/// [ThemeData.inputDecorationTheme] for the current context to the
|
||||
/// [InputDecoration], see [InputDecoration.applyDefaults].
|
||||
///
|
||||
/// For a documentation about the various parameters, see [TextField].
|
||||
///
|
||||
/// {@tool snippet}
|
||||
|
|
|
@ -393,26 +393,21 @@ class Border extends BoxBorder {
|
|||
}
|
||||
|
||||
@override
|
||||
bool get isUniform {
|
||||
bool get isUniform => _colorIsUniform && _widthIsUniform && _styleIsUniform;
|
||||
|
||||
bool get _colorIsUniform {
|
||||
final Color topColor = top.color;
|
||||
if (right.color != topColor ||
|
||||
bottom.color != topColor ||
|
||||
left.color != topColor)
|
||||
return false;
|
||||
return right.color == topColor && bottom.color == topColor && left.color == topColor;
|
||||
}
|
||||
|
||||
bool get _widthIsUniform {
|
||||
final double topWidth = top.width;
|
||||
if (right.width != topWidth ||
|
||||
bottom.width != topWidth ||
|
||||
left.width != topWidth)
|
||||
return false;
|
||||
return right.width == topWidth && bottom.width == topWidth && left.width == topWidth;
|
||||
}
|
||||
|
||||
bool get _styleIsUniform {
|
||||
final BorderStyle topStyle = top.style;
|
||||
if (right.style != topStyle ||
|
||||
bottom.style != topStyle ||
|
||||
left.style != topStyle)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return right.style == topStyle && bottom.style == topStyle && left.style == topStyle;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -522,8 +517,30 @@ class Border extends BoxBorder {
|
|||
}
|
||||
}
|
||||
|
||||
assert(borderRadius == null, 'A borderRadius can only be given for uniform borders.');
|
||||
assert(shape == BoxShape.rectangle, 'A border can only be drawn as a circle if it is uniform.');
|
||||
assert(() {
|
||||
if (borderRadius != null) {
|
||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||
ErrorSummary('A borderRadius can only be given for a uniform Border.'),
|
||||
ErrorDescription('The following is not uniform:'),
|
||||
if (!_colorIsUniform) ErrorDescription('BorderSide.color'),
|
||||
if (!_widthIsUniform) ErrorDescription('BorderSide.width'),
|
||||
if (!_styleIsUniform) ErrorDescription('BorderSide.style'),
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
assert(() {
|
||||
if (shape != BoxShape.rectangle) {
|
||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||
ErrorSummary('A Border can only be drawn as a circle if it is uniform'),
|
||||
ErrorDescription('The following is not uniform:'),
|
||||
if (!_colorIsUniform) ErrorDescription('BorderSide.color'),
|
||||
if (!_widthIsUniform) ErrorDescription('BorderSide.width'),
|
||||
if (!_styleIsUniform) ErrorDescription('BorderSide.style'),
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
|
||||
paintBorder(canvas, rect, top: top, right: right, bottom: bottom, left: left);
|
||||
}
|
||||
|
|
|
@ -1705,13 +1705,16 @@ abstract class RenderBox extends RenderObject {
|
|||
if (_size is _DebugSize) {
|
||||
assert(_size._owner == this);
|
||||
if (RenderObject.debugActiveLayout != null) {
|
||||
// We are always allowed to access our own size (for print debugging
|
||||
// and asserts if nothing else). Other than us, the only object that's
|
||||
// allowed to read our size is our parent, if they've said they will.
|
||||
// If you hit this assert trying to access a child's size, pass
|
||||
// "parentUsesSize: true" to that child's layout().
|
||||
assert(debugDoingThisResize || debugDoingThisLayout ||
|
||||
(RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent));
|
||||
assert(
|
||||
debugDoingThisResize || debugDoingThisLayout ||
|
||||
(RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent),
|
||||
'RenderBox.size accessed beyond the scope of resize, layout, or '
|
||||
'permitted parent access. RenderBox can always access its own size, '
|
||||
'otherwise, the only object that is allowed to read RenderBox.size '
|
||||
'is its parent, if they have said they will. It you hit this assert '
|
||||
'trying to access a child\'s size, pass "parentUsesSize: true" to '
|
||||
'that child\'s layout().'
|
||||
);
|
||||
}
|
||||
assert(_size == this._size);
|
||||
}
|
||||
|
|
|
@ -414,7 +414,8 @@ class SliverGridDelegateWithMaxCrossAxisExtent extends SliverGridDelegate {
|
|||
/// The ratio of the cross-axis to the main-axis extent of each child.
|
||||
final double childAspectRatio;
|
||||
|
||||
bool _debugAssertIsValid() {
|
||||
bool _debugAssertIsValid(double crossAxisExtent) {
|
||||
assert(crossAxisExtent > 0.0);
|
||||
assert(maxCrossAxisExtent > 0.0);
|
||||
assert(mainAxisSpacing >= 0.0);
|
||||
assert(crossAxisSpacing >= 0.0);
|
||||
|
@ -424,7 +425,7 @@ class SliverGridDelegateWithMaxCrossAxisExtent extends SliverGridDelegate {
|
|||
|
||||
@override
|
||||
SliverGridLayout getLayout(SliverConstraints constraints) {
|
||||
assert(_debugAssertIsValid());
|
||||
assert(_debugAssertIsValid(constraints.crossAxisExtent));
|
||||
final int crossAxisCount = (constraints.crossAxisExtent / (maxCrossAxisExtent + crossAxisSpacing)).ceil();
|
||||
final double usableCrossAxisExtent = constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
|
||||
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
|
||||
|
|
|
@ -276,6 +276,8 @@ enum StackFit {
|
|||
/// visible.
|
||||
enum Overflow {
|
||||
/// Overflowing children will be visible.
|
||||
///
|
||||
/// The visible overflow area will not accept hit testing.
|
||||
visible,
|
||||
|
||||
/// Overflowing children will be clipped to the bounds of their parent.
|
||||
|
|
|
@ -13,6 +13,41 @@ import 'framework.dart';
|
|||
/// Animated widget that automatically transitions its size over a given
|
||||
/// duration whenever the given child's size changes.
|
||||
///
|
||||
/// {@tool dartpad --template=stateful_widget_scaffold_center_freeform_state}
|
||||
/// This example makes a [Container] react to being touched, causing the child
|
||||
/// of the [AnimatedSize] widget, here a [FlutterLogo], to animate.
|
||||
///
|
||||
/// ```dart
|
||||
/// class _MyStatefulWidgetState extends State<MyStatefulWidget> with SingleTickerProviderStateMixin {
|
||||
/// double _size = 50.0;
|
||||
/// bool _large = false;
|
||||
///
|
||||
/// void _updateSize() {
|
||||
/// setState(() {
|
||||
/// _size = _large ? 250.0 : 100.0;
|
||||
/// _large = !_large;
|
||||
/// });
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return GestureDetector(
|
||||
/// onTap: () => _updateSize(),
|
||||
/// child: Container(
|
||||
/// color: Colors.amberAccent,
|
||||
/// child: AnimatedSize(
|
||||
/// curve: Curves.easeIn,
|
||||
/// vsync: this,
|
||||
/// duration: Duration(seconds: 1),
|
||||
/// child: FlutterLogo(size: _size),
|
||||
/// ),
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [SizeTransition], which changes its size based on an [Animation].
|
||||
|
|
|
@ -3285,6 +3285,9 @@ class Stack extends MultiChildRenderObjectWidget {
|
|||
/// Some children in a stack might overflow its box. When this flag is set to
|
||||
/// [Overflow.clip], children cannot paint outside of the stack's box.
|
||||
///
|
||||
/// When set to [Overflow.visible], the visible overflow area will not accept
|
||||
/// hit testing.
|
||||
///
|
||||
/// This overrides [clipBehavior] for now due to a staged roll out without
|
||||
/// breaking Google. We will remove it and only use [clipBehavior] soon.
|
||||
final Overflow overflow;
|
||||
|
|
|
@ -300,6 +300,10 @@ class _LocalizationsScope extends InheritedWidget {
|
|||
/// `Localizations.of(context)` will be rebuilt after the resources
|
||||
/// for the new locale have been loaded.
|
||||
///
|
||||
/// The `Localizations` widget also instantiates [Directionality] in order to
|
||||
/// support the appropriate [Directionality.textDirection] of the localized
|
||||
/// resources.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
///
|
||||
/// This following class is defined in terms of the
|
||||
|
|
|
@ -2404,7 +2404,11 @@ class _RouteEntry extends RouteTransitionRecord {
|
|||
assert(currentState == _RouteLifecycle.push || currentState == _RouteLifecycle.pushReplace || currentState == _RouteLifecycle.replace);
|
||||
assert(navigator != null);
|
||||
assert(navigator._debugLocked);
|
||||
assert(route._navigator == null);
|
||||
assert(
|
||||
route._navigator == null,
|
||||
'The pushed route has already been used. When pushing a route, a new '
|
||||
'Route object must be provided.',
|
||||
);
|
||||
final _RouteLifecycle previousState = currentState;
|
||||
route._navigator = navigator;
|
||||
route.install();
|
||||
|
|
|
@ -1051,12 +1051,13 @@ class ListView extends BoxScrollView {
|
|||
/// The `itemBuilder` callback will be called only with indices greater than
|
||||
/// or equal to zero and less than `itemCount`.
|
||||
///
|
||||
/// The `itemBuilder` should actually create the widget instances when called.
|
||||
/// Avoid using a builder that returns a previously-constructed widget; if the
|
||||
/// list view's children are created in advance, or all at once when the
|
||||
/// [ListView] itself is created, it is more efficient to use the [ListView]
|
||||
/// constructor. Even more efficient, however, is to create the instances on
|
||||
/// demand using this constructor's `itemBuilder` callback.
|
||||
/// The `itemBuilder` should always return a non-null widget, and actually
|
||||
/// create the widget instances when called. Avoid using a builder that
|
||||
/// returns a previously-constructed widget; if the list view's children are
|
||||
/// created in advance, or all at once when the [ListView] itself is created,
|
||||
/// it is more efficient to use the [ListView] constructor. Even more
|
||||
/// efficient, however, is to create the instances on demand using this
|
||||
/// constructor's `itemBuilder` callback.
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
|
@ -1128,11 +1129,11 @@ class ListView extends BoxScrollView {
|
|||
/// The `separatorBuilder` callback will be called with indices greater than
|
||||
/// or equal to zero and less than `itemCount - 1`.
|
||||
///
|
||||
/// The `itemBuilder` and `separatorBuilder` callbacks should actually create
|
||||
/// widget instances when called. Avoid using a builder that returns a
|
||||
/// previously-constructed widget; if the list view's children are created in
|
||||
/// advance, or all at once when the [ListView] itself is created, it is more
|
||||
/// efficient to use the [ListView] constructor.
|
||||
/// The `itemBuilder` and `separatorBuilder` callbacks should always return a
|
||||
/// non-null widget, and actually create widget instances when called. Avoid
|
||||
/// using a builder that returns a previously-constructed widget; if the list
|
||||
/// view's children are created in advance, or all at once when the [ListView]
|
||||
/// itself is created, it is more efficient to use the [ListView] constructor.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
///
|
||||
|
@ -1439,6 +1440,24 @@ class ListView extends BoxScrollView {
|
|||
/// extremities to avoid partial obstructions indicated by [MediaQuery]'s
|
||||
/// padding. To avoid this behavior, override with a zero [padding] property.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// The following example demonstrates how to override the default top padding
|
||||
/// using [MediaQuery.removePadding].
|
||||
///
|
||||
/// ```dart
|
||||
/// Widget myWidget(BuildContext context) {
|
||||
/// return MediaQuery.removePadding(
|
||||
/// context: context,
|
||||
/// removeTop: true,
|
||||
/// child: ListView.builder(
|
||||
/// itemCount: 25,
|
||||
/// itemBuilder: (BuildContext context, int index) => ListTile(title: Text('item $index')),
|
||||
/// )
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// Once code has been ported to use [CustomScrollView], other slivers, such as
|
||||
/// [SliverList] or [SliverAppBar], can be put in the [CustomScrollView.slivers]
|
||||
/// list.
|
||||
|
|
Loading…
Reference in a new issue