adding packages

This commit is contained in:
2026-01-15 14:38:46 -08:00
parent ef86e3ab6a
commit 6869cf47e5
5253 changed files with 726695 additions and 34 deletions
@@ -0,0 +1,10 @@
export 'src/utils.dart';
export 'src/accept.dart';
export 'src/base.dart';
export 'src/base_class.dart';
export 'src/widget_config.dart';
export 'src/widget_index.dart';
export 'src/material/library.dart';
export 'src/material/index.dart';
export './src/generated/library.dart';
export './src/generated/base.dart';
@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'base.dart';
import 'string_gen.dart';
import 'widget_config.dart';
typedef AcceptWidgetCallback = void Function(
BuildContext context, dynamic data);
Widget widgetAccept({
Widget child,
@required WidgetContext scope,
@required AcceptWidgetCallback onAccept,
Size size,
@required String id,
bool sizeOnlyDragging,
List<DynamicWidget> reject,
List<DynamicWidget> accept,
Widget fallback,
}) {
if (child == null && !scope.isDragging) {
return fallback;
}
return _WidgetAccept(
id: id,
scope: scope,
child: child,
onAccept: onAccept,
size: size,
sizeOnlyDragging: sizeOnlyDragging,
reject: reject,
accept: accept,
);
}
class _WidgetAccept extends StatefulWidget {
const _WidgetAccept({
Key key,
@required this.scope,
@required this.id,
@required this.onAccept,
this.child,
this.size,
this.sizeOnlyDragging = false,
this.accept,
this.reject,
}) : super(key: key);
final List<DynamicWidget> reject, accept;
final Widget child;
final String id;
final AcceptWidgetCallback onAccept;
final WidgetContext scope;
final Size size;
final bool sizeOnlyDragging;
@override
__WidgetAcceptState createState() => __WidgetAcceptState();
}
class __WidgetAcceptState extends State<_WidgetAccept> {
bool _accepting = false;
@override
void didUpdateWidget(_WidgetAccept oldWidget) {
if (widget.id != oldWidget.id) {
if (mounted) setState(() {});
}
if (widget.scope != oldWidget.scope) {
if (mounted) setState(() {});
}
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
if (widget.child != null) {
return widget.child;
}
if (!widget.scope.isDragging) {
return SizedBox.fromSize(
size: widget.sizeOnlyDragging ? null : widget.size,
child: Container(),
);
}
return SizedBox(
height: widget?.size?.height,
width: widget?.size?.width,
child: DragTarget<Map<String, dynamic>>(
onAccept: (val) {
if (mounted) {
setState(() {
_accepting = false;
});
}
if (val != null) {
final _data = val;
_data['id'] = StringGen.id;
if (_data['name'] == 'Text') {
_data['params']['style']['id'] = StringGen.id;
}
if (_data['name'] == 'Icon') {
_data['params']['0']['id'] = StringGen.id;
}
widget.onAccept(context, _data);
}
},
onLeave: (val) {
if (mounted) {
setState(() {
_accepting = false;
});
}
},
onWillAccept: (val) {
if (mounted) {
setState(() {
_accepting = true;
});
}
return _accepting;
},
builder: (context, accepted, rejected) {
return Center(
child: Container(
width: widget?.size?.width,
height: widget?.size?.height,
child: Placeholder(
color:
!_accepting ? Colors.grey : Theme.of(context).accentColor,
),
),
);
},
),
);
}
}
Map<String, dynamic> modifyAccept(Map<String, dynamic> val,
{double width, double height}) {
final _data = val;
_data['id'] = StringGen.id;
switch (_data['name']) {
case 'Container':
if (height != null) {
_data['params']['height'] = height;
}
if (width != null) {
_data['params']['width'] = width;
}
break;
default:
}
return _data;
}
@@ -0,0 +1,138 @@
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'base_class.dart';
import 'material/library.dart';
import 'widget_config.dart';
typedef UnknownWidgetBuilder = WidgetConfig Function(Map<String, dynamic>);
class DynamicWidget extends StatelessWidget implements WidgetLibrary {
static UnknownWidgetBuilder unknownWidgetBuilder;
DynamicWidget({
@required this.data,
WidgetContext widgetContext,
}) : this.widgetContext = widgetContext ?? const WidgetContext.readOnly();
final Map<String, dynamic> data;
final WidgetContext widgetContext;
@override
Map<String, WidgetConfig> get library {
return {
...MaterialBase(data, widgetContext).library,
};
}
WidgetConfig get base {
if (data != null) {
if (library[data['name']] != null) {
final _base = library[data['name']];
if (_base != null) {
return _base;
}
}
}
if (unknownWidgetBuilder != null) {
return unknownWidgetBuilder(data);
}
return null;
}
static void onAction(BuildContext context, String val) {
final data = val;
if (data == null) return null;
if (data is String) {
if (data.isEmpty) return null;
final _data = data.replaceAll('#', '');
if (_data.startsWith('message')) {
final _message = _data
.replaceAll('message(', '')
.replaceAll('(', '')
.replaceAll(')', '');
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(_message),
));
return;
}
if (_data.startsWith('navigate')) {
final _route = _data
.replaceAll('navigate(', '')
.replaceAll('(', '')
.replaceAll(')', '');
Navigator.of(context).pushNamed(_route);
return;
}
if (_data.startsWith('pop')) {
final _route = _data
.replaceAll('pop(', '')
.replaceAll('(', '')
.replaceAll(')', '');
if (_route.isNotEmpty) {
Navigator.popUntil(context, ModalRoute.withName(_route));
} else {
Navigator.of(context).pop();
}
return;
}
if (_data.startsWith('maybePop')) {
Navigator.of(context).maybePop();
return;
}
if (_data.startsWith('launch')) {
final _url = _data
.replaceAll("launch(", '')
.replaceAll('(', '')
.replaceAll(')', '')
.replaceAll("\'", '');
launch('$_url');
return;
}
if (_data.startsWith('alert')) {
final _message = _data
.replaceAll('alert(', '')
.replaceAll('(', '')
.replaceAll(')', '');
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Info'),
content: Text(_message),
actions: [
FlatButton(
child: Text('Ok'),
onPressed: () => Navigator.maybePop(context),
),
],
),
);
return;
}
}
return null;
}
Widget render(BuildContext context, [bool nullOk = false]) {
if (base != null) {
if (base is WidgetBase) {
return Builder(
builder: (context) {
return (base as WidgetBase)?.build(context);
},
);
}
}
if (nullOk) {
return null;
}
return Container();
}
@override
Widget build(BuildContext context) => render(context);
}
abstract class WidgetLibrary {
Map<String, WidgetConfig> get library;
WidgetConfig get base;
}
@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'widget_config.dart';
abstract class WidgetBase extends WidgetConfig {
Object build(BuildContext context);
}
abstract class WidgetPreferredSizedBase extends WidgetBase {
Size get preferredSize;
}
abstract class PropertyBase extends WidgetConfig {
}
abstract class AcceptData {
Map<String, dynamic> get data;
String get name;
}
class WidgetBaseData extends AcceptData {
@override
final Map<String, dynamic> data;
@override
final String name;
WidgetBaseData({
@required this.data,
@required this.name,
});
}
class WidgetPreferredSizeBaseData extends WidgetBaseData {
@override
final Map<String, dynamic> data;
@override
final String name;
final Size size;
WidgetPreferredSizeBaseData({
@required this.data,
@required this.name,
@required this.size,
});
}
class BottomNavigationBarItemBaseData extends AcceptData {
@override
final Map<String, dynamic> data;
@override
final String name;
BottomNavigationBarItemBaseData({
@required this.data,
@required this.name,
});
}
@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
export 'package:flutter/material.dart';
abstract class BaseWidget extends Base {
Widget render(BuildContext context);
}
abstract class Base {
String get description;
Map<String, dynamic> toJson();
}
@@ -0,0 +1,39 @@
import '../base.dart';
class AboutDialogBase extends BaseWidget {
AboutDialogBase();
factory AboutDialogBase.fromJson(Map<String, dynamic> data) {
return AboutDialogBase();
}
@override
String get description => r"""
An about box. This is a dialog box with the application's icon, name,
version number, and copyright, plus a button to show licenses for software
used by the application.
To show an [AboutDialog], use [showAboutDialog].
{@youtube 560 315 https://www.youtube.com/watch?v=YFCSODyFxbE}
If the application has a [Drawer], the [AboutListTile] widget can make the
process of showing an about dialog simpler.
The [AboutDialog] shown by [showAboutDialog] includes a button that calls
[showLicensePage].
The licenses shown on the [LicensePage] are those returned by the
[LicenseRegistry] API, which can be used to add more licenses to the list.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,105 @@
import '../base.dart';
class AboutListTileBase extends BaseWidget {
AboutListTileBase();
factory AboutListTileBase.fromJson(Map<String, dynamic> data) {
return AboutListTileBase();
}
@override
String get description => r"""
A [ListTile] that shows an about box.
This widget is often added to an app's [Drawer]. When tapped it shows
an about box dialog with [showAboutDialog].
The about box will include a button that shows licenses for software used by
the application. The licenses shown are those returned by the
[LicenseRegistry] API, which can be used to add more licenses to the list.
If your application does not have a [Drawer], you should provide an
affordance to call [showAboutDialog] or (at least) [showLicensePage].
{@tool dartpad --template=stateless_widget_material}
This sample shows two ways to open [AboutDialog]. The first one
uses an [AboutListTile], and the second uses the [showAboutDialog] function.
```dart
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.bodyText2;
final List<Widget> aboutBoxChildren = <Widget>[
SizedBox(height: 24),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
style: textStyle,
text: "Flutter is Google's UI toolkit for building beautiful, "
'natively compiled applications for mobile, web, and desktop '
'from a single codebase. Learn more about Flutter at '
),
TextSpan(
style: textStyle.copyWith(color: Theme.of(context).accentColor),
text: 'https://flutter.dev'
),
TextSpan(
style: textStyle,
text: '.'
),
],
),
),
];
return Scaffold(
appBar: AppBar(
title: Text('Show About Example'),
),
drawer: Drawer(
child: SingleChildScrollView(
child: SafeArea(
child: AboutListTile(
icon: Icon(Icons.info),
applicationIcon: FlutterLogo(),
applicationName: 'Show About Example',
applicationVersion: 'August 2019',
applicationLegalese: '\u{a9} 2014 The Flutter Authors',
aboutBoxChildren: aboutBoxChildren,
),
),
),
),
body: Center(
child: ElevatedButton(
child: Text('Show About Example'),
onPressed: () {
showAboutDialog(
context: context,
applicationIcon: FlutterLogo(),
applicationName: 'Show About Example',
applicationVersion: 'August 2019',
applicationLegalese: '\u{a9} 2014 The Flutter Authors',
children: aboutBoxChildren,
);
},
),
),
);
}
```
{@end-tool}
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,37 @@
import '../base.dart';
class AbsorbPointerBase extends BaseWidget {
AbsorbPointerBase();
factory AbsorbPointerBase.fromJson(Map<String, dynamic> data) {
return AbsorbPointerBase();
}
@override
String get description => r"""
A widget that absorbs pointers during hit testing.
When [absorbing] is true, this widget prevents its subtree from receiving
pointer events by terminating hit testing at itself. It still consumes space
during layout and paints its child as usual. It just prevents its children
from being the target of located events, because it returns true from
[RenderBox.hitTest].
{@youtube 560 315 https://www.youtube.com/watch?v=65HoWqBboI8}
See also:
* [IgnorePointer], which also prevents its children from receiving pointer
events but is itself invisible to hit testing.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,54 @@
import '../base.dart';
class AbstractNodeBase extends BaseWidget {
AbstractNodeBase();
factory AbstractNodeBase.fromJson(Map<String, dynamic> data) {
return AbstractNodeBase();
}
@override
String get description => r"""
An abstract node in a tree.
AbstractNode has as notion of depth, attachment, and parent, but does not
have a model for children.
When a subclass is changing the parent of a child, it should call either
`parent.adoptChild(child)` or `parent.dropChild(child)` as appropriate.
Subclasses can expose an API for manipulating the tree if desired (e.g. a
setter for a `child` property, or an `add()` method to manipulate a list).
The current parent node is exposed by the [parent] property.
The current attachment state is exposed by [attached]. The root of any tree
that is to be considered attached should be manually attached by calling
[attach]. Other than that, the [attach] and [detach] methods should not be
called directly; attachment is managed automatically by the aforementioned
[adoptChild] and [dropChild] methods.
Subclasses that have children must override [attach] and [detach] as
described in the documentation for those methods.
Nodes always have a [depth] greater than their ancestors'. There's no
guarantee regarding depth between siblings. The depth of a node is used to
ensure that nodes are processed in depth order. The [depth] of a child can
be more than one greater than the [depth] of the parent, because the [depth]
values are never decreased: all that matters is that it's greater than the
parent. Consider a tree with a root node A, a child B, and a grandchild C.
Initially, A will have [depth] 0, B [depth] 1, and C [depth] 2. If C is
moved to be a child of A, sibling of B, then the numbers won't change. C's
[depth] will still be 2. The [depth] is automatically maintained by the
[adoptChild] and [dropChild] methods.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,25 @@
import '../base.dart';
class AccumulatorBase extends BaseWidget {
AccumulatorBase();
factory AccumulatorBase.fromJson(Map<String, dynamic> data) {
return AccumulatorBase();
}
@override
String get description => r"""
Mutable wrapper of an integer that can be passed by reference to track a
value across a recursive stack.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,70 @@
import '../base.dart';
class ActionChipBase extends BaseWidget {
ActionChipBase();
factory ActionChipBase.fromJson(Map<String, dynamic> data) {
return ActionChipBase();
}
@override
String get description => r"""
A material design action chip.
Action chips are a set of options which trigger an action related to primary
content. Action chips should appear dynamically and contextually in a UI.
Action chips can be tapped to trigger an action or show progress and
confirmation. They cannot be disabled; if the action is not applicable, the
chip should not be included in the interface. (This contrasts with buttons,
where unavailable choices are usually represented as disabled controls.)
Action chips are displayed after primary content, such as below a card or
persistently at the bottom of a screen.
The material button widgets, [ElevatedButton], [TextButton], and
[OutlinedButton], are an alternative to action chips, which should appear
statically and consistently in a UI.
Requires one of its ancestors to be a [Material] widget.
{@tool snippet}
```dart
ActionChip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Text('AB'),
),
label: Text('Aaron Burr'),
onPressed: () {
print("If you stand for nothing, Burr, whatll you fall for?");
}
)
```
{@end-tool}
See also:
* [Chip], a chip that displays information and can be deleted.
* [InputChip], a chip that represents a complex piece of information, such
as an entity (person, place, or thing) or conversational text, in a
compact form.
* [ChoiceChip], allows a single selection from a set of options. Choice
chips contain related descriptive text or categories.
* [CircleAvatar], which shows images or initials of people.
* [Wrap], A widget that displays its children in multiple horizontal or
vertical runs.
* <https://material.io/design/components/chips.html>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,31 @@
import '../base.dart';
class ActionDispatcherBase extends BaseWidget {
ActionDispatcherBase();
factory ActionDispatcherBase.fromJson(Map<String, dynamic> data) {
return ActionDispatcherBase();
}
@override
String get description => r"""
An action dispatcher that simply invokes the actions given to it.
See also:
- [ShortcutManager], that uses this class to invoke actions.
- [Shortcuts] widget, which defines key mappings to [Intent]s.
- [Actions] widget, which defines a mapping between a in [Intent] type and
an [Action].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,34 @@
import '../base.dart';
class ActionListenerBase extends BaseWidget {
ActionListenerBase();
factory ActionListenerBase.fromJson(Map<String, dynamic> data) {
return ActionListenerBase();
}
@override
String get description => r"""
A helper widget for making sure that listeners on an action are removed properly.
Listeners on the [Action] class must have their listener callbacks removed
with [Action.removeActionListener] when the listener is disposed of. This widget
helps with that, by providing a lifetime for the connection between the
[listener] and the [Action], and by handling the adding and removing of
the [listener] at the right points in the widget lifecycle.
If you listen to an [Action] widget in a widget hierarchy, you should use
this widget. If you are using an [Action] outside of a widget context, then
you must call removeListener yourself.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,37 @@
import '../base.dart';
class ActionsBase extends BaseWidget {
ActionsBase();
factory ActionsBase.fromJson(Map<String, dynamic> data) {
return ActionsBase();
}
@override
String get description => r"""
A widget that establishes an [ActionDispatcher] and a map of [Intent] to
[Action] to be used by its descendants when invoking an [Action].
Actions are typically invoked using [Actions.invoke] with the context
containing the ambient [Actions] widget.
See also:
* [ActionDispatcher], the object that this widget uses to manage actions.
* [Action], a class for containing and defining an invocation of a user
action.
* [Intent], a class that holds a unique [LocalKey] identifying an action,
as well as configuration information for running the [Action].
* [Shortcuts], a widget used to bind key combinations to [Intent]s.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,24 @@
import '../base.dart';
class ActivateIntentBase extends BaseWidget {
ActivateIntentBase();
factory ActivateIntentBase.fromJson(Map<String, dynamic> data) {
return ActivateIntentBase();
}
@override
String get description => r"""
An intent that activates the currently focused control.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,92 @@
import '../base.dart';
class AlertDialogBase extends BaseWidget {
AlertDialogBase();
factory AlertDialogBase.fromJson(Map<String, dynamic> data) {
return AlertDialogBase();
}
@override
String get description => r"""
A material design alert dialog.
An alert dialog informs the user about situations that require
acknowledgement. An alert dialog has an optional title and an optional list
of actions. The title is displayed above the content and the actions are
displayed below the content.
{@youtube 560 315 https://www.youtube.com/watch?v=75CsnyRXf5I}
If the content is too large to fit on the screen vertically, the dialog will
display the title and the actions and let the content overflow, which is
rarely desired. Consider using a scrolling widget for [content], such as
[SingleChildScrollView], to avoid overflow. (However, be aware that since
[AlertDialog] tries to size itself using the intrinsic dimensions of its
children, widgets such as [ListView], [GridView], and [CustomScrollView],
which use lazy viewports, will not work. If this is a problem, consider
using [Dialog] directly.)
For dialogs that offer the user a choice between several options, consider
using a [SimpleDialog].
Typically passed as the child widget to [showDialog], which displays the
dialog.
{@animation 350 622 https://flutter.github.io/assets-for-api-docs/assets/material/alert_dialog.mp4}
{@tool snippet}
This snippet shows a method in a [State] which, when called, displays a dialog box
and returns a [Future] that completes when the dialog is dismissed.
```dart
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('AlertDialog Title'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('This is a demo alert dialog.'),
Text('Would you like to approve of this message?'),
],
),
),
actions: <Widget>[
TextButton(
child: Text('Approve'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
```
{@end-tool}
See also:
* [SimpleDialog], which handles the scrolling of the contents but has no [actions].
* [Dialog], on which [AlertDialog] and [SimpleDialog] are based.
* [CupertinoAlertDialog], an iOS-styled alert dialog.
* [showDialog], which actually displays the dialog and returns its result.
* <https://material.io/design/components/dialogs.html#alert-dialog>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,151 @@
import '../base.dart';
class AlignBase extends BaseWidget {
AlignBase();
factory AlignBase.fromJson(Map<String, dynamic> data) {
return AlignBase();
}
@override
String get description => r"""
A widget that aligns its child within itself and optionally sizes itself
based on the child's size.
For example, to align a box at the bottom right, you would pass this box a
tight constraint that is bigger than the child's natural size,
with an alignment of [Alignment.bottomRight].
{@youtube 560 315 https://www.youtube.com/watch?v=g2E7yl3MwMk}
This widget will be as big as possible if its dimensions are constrained and
[widthFactor] and [heightFactor] are null. If a dimension is unconstrained
and the corresponding size factor is null then the widget will match its
child's size in that dimension. If a size factor is non-null then the
corresponding dimension of this widget will be the product of the child's
dimension and the size factor. For example if widthFactor is 2.0 then
the width of this widget will always be twice its child's width.
## How it works
The [alignment] property describes a point in the `child`'s coordinate system
and a different point in the coordinate system of this widget. The [Align]
widget positions the `child` such that both points are lined up on top of
each other.
{@tool snippet}
The [Align] widget in this example uses one of the defined constants from
[Alignment], [Alignment.topRight]. This places the [FlutterLogo] in the top
right corner of the parent blue [Container].
![A blue square container with the Flutter logo in the top right corner.](https://flutter.github.io/assets-for-api-docs/assets/widgets/align_constant.png)
```dart
Center(
child: Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: Alignment.topRight,
child: FlutterLogo(
size: 60,
),
),
),
)
```
{@end-tool}
{@tool snippet}
The [Alignment] used in the following example defines a single point:
* (0.2 * width of [FlutterLogo]/2 + width of [FlutterLogo]/2, 0.6 * height
of [FlutterLogo]/2 + height of [FlutterLogo]/2) = (36.0, 48.0).
The [Alignment] class uses a coordinate system with an origin in the center
of the [Container], as shown with the [Icon] above. [Align] will place the
[FlutterLogo] at (36.0, 48.0) according to this coordinate system.
![A blue square container with the Flutter logo positioned according to the
Alignment specified above. A point is marked at the center of the container
for the origin of the Alignment coordinate system.](https://flutter.github.io/assets-for-api-docs/assets/widgets/align_alignment.png)
```dart
Center(
child: Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: Alignment(0.2, 0.6),
child: FlutterLogo(
size: 60,
),
),
),
)
```
{@end-tool}
{@tool snippet}
The [FractionalOffset] used in the following example defines two points:
* (0.2 * width of [FlutterLogo], 0.6 * height of [FlutterLogo]) = (12.0, 36.0)
in the coordinate system of the blue container.
* (0.2 * width of [Align], 0.6 * height of [Align]) = (24.0, 72.0) in the
coordinate system of the [Align] widget.
The [Align] widget positions the [FlutterLogo] such that the two points are on
top of each other. In this example, the top left of the [FlutterLogo] will
be placed at (24.0, 72.0) - (12.0, 36.0) = (12.0, 36.0) from the top left of
the [Align] widget.
The [FractionalOffset] class uses a coordinate system with an origin in the top-left
corner of the [Container] in difference to the center-oriented system used in
the example above with [Alignment].
![A blue square container with the Flutter logo positioned according to the
FractionalOffset specified above. A point is marked at the top left corner
of the container for the origin of the FractionalOffset coordinate system.](https://flutter.github.io/assets-for-api-docs/assets/widgets/align_fractional_offset.png)
```dart
Center(
child: Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: FractionalOffset(0.2, 0.6),
child: FlutterLogo(
size: 60,
),
),
),
)
```
{@end-tool}
See also:
* [AnimatedAlign], which animates changes in [alignment] smoothly over a
given duration.
* [CustomSingleChildLayout], which uses a delegate to control the layout of
a single child.
* [Center], which is the same as [Align] but with the [alignment] always
set to [Alignment.center].
* [FractionallySizedBox], which sizes its child based on a fraction of its
own size and positions the child according to an [Alignment] value.
* The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,43 @@
import '../base.dart';
class AlignTransitionBase extends BaseWidget {
AlignTransitionBase();
factory AlignTransitionBase.fromJson(Map<String, dynamic> data) {
return AlignTransitionBase();
}
@override
String get description => r"""
Animated version of an [Align] that animates its [Align.alignment] property.
Here's an illustration of the [DecoratedBoxTransition] widget, with it's
[DecoratedBoxTransition.decoration] animated by a [CurvedAnimation] set to
[Curves.decelerate]:
{@animation 300 378 https://flutter.github.io/assets-for-api-docs/assets/widgets/align_transition.mp4}
See also:
* [AnimatedAlign], which animates changes to the [alignment] without
taking an explicit [Animation] argument.
* [PositionedTransition], a widget that animates its child from a start
position to an end position over the lifetime of the animation.
* [RelativePositionedTransition], a widget that transitions its child's
position based on the value of a rectangle relative to a bounding box.
* [SizeTransition], a widget that animates its own size and clips and
aligns its child.
* [SlideTransition], a widget that animates the position of a widget
relative to its normal position.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,63 @@
import '../base.dart';
class AlignmentBase extends BaseWidget {
AlignmentBase();
factory AlignmentBase.fromJson(Map<String, dynamic> data) {
return AlignmentBase();
}
@override
String get description => r"""
A point within a rectangle.
`Alignment(0.0, 0.0)` represents the center of the rectangle. The distance
from -1.0 to +1.0 is the distance from one side of the rectangle to the
other side of the rectangle. Therefore, 2.0 units horizontally (or
vertically) is equivalent to the width (or height) of the rectangle.
`Alignment(-1.0, -1.0)` represents the top left of the rectangle.
`Alignment(1.0, 1.0)` represents the bottom right of the rectangle.
`Alignment(0.0, 3.0)` represents a point that is horizontally centered with
respect to the rectangle and vertically below the bottom of the rectangle by
the height of the rectangle.
`Alignment(0.0, -0.5)` represents a point that is horizontally centered with
respect to the rectangle and vertically half way between the top edge and
the center.
`Alignment(x, y)` in a rectangle with height h and width w describes
the point (x * w/2 + w/2, y * h/2 + h/2) in the coordinate system of the
rectangle.
[Alignment] uses visual coordinates, which means increasing [x] moves the
point from left to right. To support layouts with a right-to-left
[TextDirection], consider using [AlignmentDirectional], in which the
direction the point moves when increasing the horizontal value depends on
the [TextDirection].
A variety of widgets use [Alignment] in their configuration, most
notably:
* [Align] positions a child according to an [Alignment].
See also:
* [AlignmentDirectional], which has a horizontal coordinate orientation
that depends on the [TextDirection].
* [AlignmentGeometry], which is an abstract type that is agnostic as to
whether the horizontal direction depends on the [TextDirection].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,34 @@
import '../base.dart';
class AlignmentDirectionalBase extends BaseWidget {
AlignmentDirectionalBase();
factory AlignmentDirectionalBase.fromJson(Map<String, dynamic> data) {
return AlignmentDirectionalBase();
}
@override
String get description => r"""
An offset that's expressed as a fraction of a [Size], but whose horizontal
component is dependent on the writing direction.
This can be used to indicate an offset from the left in [TextDirection.ltr]
text and an offset from the right in [TextDirection.rtl] text without having
to be aware of the current text direction.
See also:
* [Alignment], a variant that is defined in physical terms (i.e.
whose horizontal component does not depend on the text direction).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,33 @@
import '../base.dart';
class AlignmentGeometryTweenBase extends BaseWidget {
AlignmentGeometryTweenBase();
factory AlignmentGeometryTweenBase.fromJson(Map<String, dynamic> data) {
return AlignmentGeometryTweenBase();
}
@override
String get description => r"""
An interpolation between two [AlignmentGeometry].
This class specializes the interpolation of [Tween<AlignmentGeometry>]
to be appropriate for alignments.
See [Tween] for a discussion on how to use interpolation objects.
See also:
* [AlignmentTween], which interpolates between two [Alignment] objects.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,34 @@
import '../base.dart';
class AlignmentTweenBase extends BaseWidget {
AlignmentTweenBase();
factory AlignmentTweenBase.fromJson(Map<String, dynamic> data) {
return AlignmentTweenBase();
}
@override
String get description => r"""
An interpolation between two alignments.
This class specializes the interpolation of [Tween<Alignment>] to be
appropriate for alignments.
See [Tween] for a discussion on how to use interpolation objects.
See also:
* [AlignmentGeometryTween], which interpolates between two
[AlignmentGeometry] objects.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,41 @@
import '../base.dart';
class AlwaysScrollableScrollPhysicsBase extends BaseWidget {
AlwaysScrollableScrollPhysicsBase();
factory AlwaysScrollableScrollPhysicsBase.fromJson(Map<String, dynamic> data) {
return AlwaysScrollableScrollPhysicsBase();
}
@override
String get description => r"""
Scroll physics that always lets the user scroll.
This overrides the default behavior which is to disable scrolling
when there is no content to scroll. It does not override the
handling of overscrolling.
On Android, overscrolls will be clamped by default and result in an
overscroll glow. On iOS, overscrolls will load a spring that will return the
scroll view to its normal range when released.
See also:
* [ScrollPhysics], which can be used instead of this class when the default
behavior is desired instead.
* [BouncingScrollPhysics], which provides the bouncing overscroll behavior
found on iOS.
* [ClampingScrollPhysics], which provides the clamping overscroll behavior
found on Android.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,26 @@
import '../base.dart';
class AlwaysStoppedAnimationBase extends BaseWidget {
AlwaysStoppedAnimationBase();
factory AlwaysStoppedAnimationBase.fromJson(Map<String, dynamic> data) {
return AlwaysStoppedAnimationBase();
}
@override
String get description => r"""
An animation that is always stopped at a given value.
The [status] is always [AnimationStatus.forward].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,24 @@
import '../base.dart';
class AndroidMotionEventBase extends BaseWidget {
AndroidMotionEventBase();
factory AndroidMotionEventBase.fromJson(Map<String, dynamic> data) {
return AndroidMotionEventBase();
}
@override
String get description => r"""
A Dart version of Android's [MotionEvent](https://developer.android.com/reference/android/view/MotionEvent).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,26 @@
import '../base.dart';
class AndroidPointerCoordsBase extends BaseWidget {
AndroidPointerCoordsBase();
factory AndroidPointerCoordsBase.fromJson(Map<String, dynamic> data) {
return AndroidPointerCoordsBase();
}
@override
String get description => r"""
Position information for an Android pointer.
A Dart version of Android's [MotionEvent.PointerCoords](https://developer.android.com/reference/android/view/MotionEvent.PointerCoords).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,26 @@
import '../base.dart';
class AndroidPointerPropertiesBase extends BaseWidget {
AndroidPointerPropertiesBase();
factory AndroidPointerPropertiesBase.fromJson(Map<String, dynamic> data) {
return AndroidPointerPropertiesBase();
}
@override
String get description => r"""
Properties of an Android pointer.
A Dart version of Android's [MotionEvent.PointerProperties](https://developer.android.com/reference/android/view/MotionEvent.PointerProperties).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,65 @@
import '../base.dart';
class AndroidViewBase extends BaseWidget {
AndroidViewBase();
factory AndroidViewBase.fromJson(Map<String, dynamic> data) {
return AndroidViewBase();
}
@override
String get description => r"""
Embeds an Android view in the Widget hierarchy.
Requires Android API level 20 or greater.
Embedding Android views is an expensive operation and should be avoided when a Flutter
equivalent is possible.
The embedded Android view is painted just like any other Flutter widget and transformations
apply to it as well.
{@template flutter.widgets.platformViews.layout}
The widget fills all available space, the parent of this object must provide bounded layout
constraints.
{@endtemplate}
{@template flutter.widgets.platformViews.gestures}
The widget participates in Flutter's gesture arenas, and dispatches touch events to the
platform view iff it won the arena. Specific gestures that should be dispatched to the platform
view can be specified in the `gestureRecognizers` constructor parameter. If
the set of gesture recognizers is empty, a gesture will be dispatched to the platform
view iff it was not claimed by any other gesture recognizer.
{@endtemplate}
The Android view object is created using a [PlatformViewFactory](/javadoc/io/flutter/plugin/platform/PlatformViewFactory.html).
Plugins can register platform view factories with [PlatformViewRegistry#registerViewFactory](/javadoc/io/flutter/plugin/platform/PlatformViewRegistry.html#registerViewFactory-java.lang.String-io.flutter.plugin.platform.PlatformViewFactory-).
Registration is typically done in the plugin's registerWith method, e.g:
```java
public static void registerWith(Registrar registrar) {
registrar.platformViewRegistry().registerViewFactory("webview", WebViewFactory(registrar.messenger()));
}
```
{@template flutter.widgets.platformViews.lifetime}
The platform view's lifetime is the same as the lifetime of the [State] object for this widget.
When the [State] is disposed the platform view (and auxiliary resources) are lazily
released (some resources are immediately released and some by platform garbage collector).
A stateful widget's state is disposed when the widget is removed from the tree or when it is
moved within the tree. If the stateful widget has a key and it's only moved relative to its siblings,
or it has a [GlobalKey] and it's moved within the tree, it will not be disposed.
{@endtemplate}
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,38 @@
import '../base.dart';
class AndroidViewSurfaceBase extends BaseWidget {
AndroidViewSurfaceBase();
factory AndroidViewSurfaceBase.fromJson(Map<String, dynamic> data) {
return AndroidViewSurfaceBase();
}
@override
String get description => r"""
Integrates an Android view with Flutter's compositor, touch, and semantics subsystems.
The compositor integration is done by adding a [PlatformViewLayer] to the layer tree. [PlatformViewLayer]
isn't supported on all platforms. Custom Flutter embedders can support
[PlatformViewLayer]s by implementing a SystemCompositor.
The widget fills all available space, the parent of this object must provide bounded layout
constraints.
If the associated platform view is not created, the [AndroidViewSurface] does not paint any contents.
See also:
* [AndroidView] which embeds an Android platform view in the widget hierarchy using a [TextureLayer].
* [UiKitView] which embeds an iOS platform view in the widget hierarchy.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,80 @@
import '../base.dart';
class AnimatedAlignBase extends BaseWidget {
AnimatedAlignBase();
factory AnimatedAlignBase.fromJson(Map<String, dynamic> data) {
return AnimatedAlignBase();
}
@override
String get description => r"""
Animated version of [Align] which automatically transitions the child's
position over a given duration whenever the given [alignment] changes.
Here's an illustration of what this can look like, using a [curve] of
[Curves.fastOutSlowIn].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_align.mp4}
For the animation, you can choose a [curve] as well as a [duration] and the
widget will automatically animate to the new target [alignment]. If you require
more control over the animation (e.g. if you want to stop it mid-animation),
consider using an [AlignTransition] instead, which takes a provided
[Animation] as argument. While that allows you to fine-tune the animation,
it also requires more development overhead as you have to manually manage
the lifecycle of the underlying [AnimationController].
{@tool dartpad --template=stateful_widget_scaffold}
The following code implements the [AnimatedAlign] widget, using a [curve] of
[Curves.fastOutSlowIn].
```dart
bool selected = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Center(
child: Container(
width: 250.0,
height: 250.0,
color: Colors.red,
child: AnimatedAlign(
alignment: selected ? Alignment.topRight : Alignment.bottomLeft,
duration: const Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
child: const FlutterLogo(size: 50.0),
),
),
),
);
}
```
{@end-tool}
See also:
* [AnimatedContainer], which can transition more values at once.
* [AnimatedPadding], which can animate the padding instead of the
alignment.
* [AnimatedPositioned], which, as a child of a [Stack], automatically
transitions its child's position over a given duration whenever the given
position changes.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,102 @@
import '../base.dart';
class AnimatedBuilderBase extends BaseWidget {
AnimatedBuilderBase();
factory AnimatedBuilderBase.fromJson(Map<String, dynamic> data) {
return AnimatedBuilderBase();
}
@override
String get description => r"""
A general-purpose widget for building animations.
AnimatedBuilder is useful for more complex widgets that wish to include
an animation as part of a larger build function. To use AnimatedBuilder,
simply construct the widget and pass it a builder function.
For simple cases without additional state, consider using
[AnimatedWidget].
{@youtube 560 315 https://www.youtube.com/watch?v=N-RiyZlv8v8}
## Performance optimizations
If your [builder] function contains a subtree that does not depend on the
animation, it's more efficient to build that subtree once instead of
rebuilding it on every animation tick.
If you pass the pre-built subtree as the [child] parameter, the
AnimatedBuilder will pass it back to your builder function so that you
can incorporate it into your build.
Using this pre-built child is entirely optional, but can improve
performance significantly in some cases and is therefore a good practice.
{@tool dartpad --template=stateful_widget_material_ticker}
This code defines a widget that spins a green square continually. It is
built with an [AnimatedBuilder] and makes use of the [child] feature to
avoid having to rebuild the [Container] each time.
```dart imports
import 'dart:math' as math;
```
```dart
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
child: Container(
width: 200.0,
height: 200.0,
color: Colors.green,
child: const Center(
child: Text('Whee!'),
),
),
builder: (BuildContext context, Widget child) {
return Transform.rotate(
angle: _controller.value * 2.0 * math.pi,
child: child,
);
},
);
}
```
{@end-tool}
See also:
* [TweenAnimationBuilder], which animates a property to a target value
without requiring manual management of an [AnimationController].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,83 @@
import '../base.dart';
class AnimatedContainerBase extends BaseWidget {
AnimatedContainerBase();
factory AnimatedContainerBase.fromJson(Map<String, dynamic> data) {
return AnimatedContainerBase();
}
@override
String get description => r"""
Animated version of [Container] that gradually changes its values over a period of time.
The [AnimatedContainer] will automatically animate between the old and
new values of properties when they change using the provided curve and
duration. Properties that are null are not animated. Its child and
descendants are not animated.
This class is useful for generating simple implicit transitions between
different parameters to [Container] with its internal [AnimationController].
For more complex animations, you'll likely want to use a subclass of
[AnimatedWidget] such as the [DecoratedBoxTransition] or use your own
[AnimationController].
{@youtube 560 315 https://www.youtube.com/watch?v=yI-8QHpGIP4}
{@tool dartpad --template=stateful_widget_scaffold}
The following example (depicted above) transitions an AnimatedContainer
between two states. It adjusts the `height`, `width`, `color`, and
[alignment] properties when tapped.
```dart
bool selected = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Center(
child: AnimatedContainer(
width: selected ? 200.0 : 100.0,
height: selected ? 100.0 : 200.0,
color: selected ? Colors.red : Colors.blue,
alignment: selected ? Alignment.center : AlignmentDirectional.topCenter,
duration: Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: FlutterLogo(size: 75),
),
),
);
}
```
{@end-tool}
See also:
* [AnimatedPadding], which is a subset of this widget that only
supports animating the [padding].
* The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
* [AnimatedPositioned], which, as a child of a [Stack], automatically
transitions its child's position over a given duration whenever the given
position changes.
* [AnimatedAlign], which automatically transitions its child's
position over a given duration whenever the given [alignment] changes.
* [AnimatedSwitcher], which switches out a child for a new one with a customizable transition.
* [AnimatedCrossFade], which fades between two children and interpolates their sizes.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,69 @@
import '../base.dart';
class AnimatedCrossFadeBase extends BaseWidget {
AnimatedCrossFadeBase();
factory AnimatedCrossFadeBase.fromJson(Map<String, dynamic> data) {
return AnimatedCrossFadeBase();
}
@override
String get description => r"""
A widget that cross-fades between two given children and animates itself
between their sizes.
{@youtube 560 315 https://www.youtube.com/watch?v=PGK2UUAyE54}
The animation is controlled through the [crossFadeState] parameter.
[firstCurve] and [secondCurve] represent the opacity curves of the two
children. The [firstCurve] is inverted, i.e. it fades out when providing a
growing curve like [Curves.linear]. The [sizeCurve] is the curve used to
animate between the size of the fading-out child and the size of the
fading-in child.
This widget is intended to be used to fade a pair of widgets with the same
width. In the case where the two children have different heights, the
animation crops overflowing children during the animation by aligning their
top edge, which means that the bottom will be clipped.
The animation is automatically triggered when an existing
[AnimatedCrossFade] is rebuilt with a different value for the
[crossFadeState] property.
{@tool snippet}
This code fades between two representations of the Flutter logo. It depends
on a boolean field `_first`; when `_first` is true, the first logo is shown,
otherwise the second logo is shown. When the field changes state, the
[AnimatedCrossFade] widget cross-fades between the two forms of the logo
over three seconds.
```dart
AnimatedCrossFade(
duration: const Duration(seconds: 3),
firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
)
```
{@end-tool}
See also:
* [AnimatedOpacity], which fades between nothing and a single child.
* [AnimatedSwitcher], which switches out a child for a new one with a
customizable transition, supporting multiple cross-fades at once.
* [AnimatedSize], the lower-level widget which [AnimatedCrossFade] uses to
automatically change size.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,43 @@
import '../base.dart';
class AnimatedDefaultTextStyleBase extends BaseWidget {
AnimatedDefaultTextStyleBase();
factory AnimatedDefaultTextStyleBase.fromJson(Map<String, dynamic> data) {
return AnimatedDefaultTextStyleBase();
}
@override
String get description => r"""
Animated version of [DefaultTextStyle] which automatically transitions the
default text style (the text style to apply to descendant [Text] widgets
without explicit style) over a given duration whenever the given style
changes.
The [textAlign], [softWrap], [overflow], [maxLines], [textWidthBasis]
and [textHeightBehavior] properties are not animated and take effect
immediately when changed.
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.elasticInOut].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_default_text_style.mp4}
For the animation, you can choose a [curve] as well as a [duration] and the
widget will automatically animate to the new default text style. If you require
more control over the animation (e.g. if you want to stop it mid-animation),
consider using a [DefaultTextStyleTransition] instead, which takes a provided
[Animation] as argument. While that allows you to fine-tune the animation,
it also requires more development overhead as you have to manually manage
the lifecycle of the underlying [AnimationController].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,40 @@
import '../base.dart';
class AnimatedIconBase extends BaseWidget {
AnimatedIconBase();
factory AnimatedIconBase.fromJson(Map<String, dynamic> data) {
return AnimatedIconBase();
}
@override
String get description => r"""
Shows an animated icon at a given animation [progress].
The available icons are specified in [AnimatedIcons].
{@youtube 560 315 https://www.youtube.com/watch?v=pJcbh8pbvJs}
{@tool snippet}
```dart
AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: controller,
semanticLabel: 'Show menu',
)
```
{@end-tool}
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,250 @@
import '../base.dart';
class AnimatedListBase extends BaseWidget {
AnimatedListBase();
factory AnimatedListBase.fromJson(Map<String, dynamic> data) {
return AnimatedListBase();
}
@override
String get description => r"""
A scrolling container that animates items when they are inserted or removed.
This widget's [AnimatedListState] can be used to dynamically insert or
remove items. To refer to the [AnimatedListState] either provide a
[GlobalKey] or use the static [of] method from an item's input callback.
This widget is similar to one created by [ListView.builder].
{@youtube 560 315 https://www.youtube.com/watch?v=ZtfItHwFlZ8}
{@tool dartpad --template=freeform}
This sample application uses an [AnimatedList] to create an effect when
items are removed or added to the list.
```dart imports
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
```
```dart
class AnimatedListSample extends StatefulWidget {
@override
_AnimatedListSampleState createState() => _AnimatedListSampleState();
}
class _AnimatedListSampleState extends State<AnimatedListSample> {
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
ListModel<int> _list;
int _selectedItem;
int _nextItem; // The next item inserted when the user presses the '+' button.
@override
void initState() {
super.initState();
_list = ListModel<int>(
listKey: _listKey,
initialItems: <int>[0, 1, 2],
removedItemBuilder: _buildRemovedItem,
);
_nextItem = 3;
}
// Used to build list items that haven't been removed.
Widget _buildItem(BuildContext context, int index, Animation<double> animation) {
return CardItem(
animation: animation,
item: _list[index],
selected: _selectedItem == _list[index],
onTap: () {
setState(() {
_selectedItem = _selectedItem == _list[index] ? null : _list[index];
});
},
);
}
// Used to build an item after it has been removed from the list. This
// method is needed because a removed item remains visible until its
// animation has completed (even though it's gone as far this ListModel is
// concerned). The widget will be used by the
// [AnimatedListState.removeItem] method's
// [AnimatedListRemovedItemBuilder] parameter.
Widget _buildRemovedItem(int item, BuildContext context, Animation<double> animation) {
return CardItem(
animation: animation,
item: item,
selected: false,
// No gesture detector here: we don't want removed items to be interactive.
);
}
// Insert the "next item" into the list model.
void _insert() {
final int index = _selectedItem == null ? _list.length : _list.indexOf(_selectedItem);
_list.insert(index, _nextItem++);
}
// Remove the selected item from the list model.
void _remove() {
if (_selectedItem != null) {
_list.removeAt(_list.indexOf(_selectedItem));
setState(() {
_selectedItem = null;
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('AnimatedList'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
onPressed: _insert,
tooltip: 'insert a new item',
),
IconButton(
icon: const Icon(Icons.remove_circle),
onPressed: _remove,
tooltip: 'remove the selected item',
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: AnimatedList(
key: _listKey,
initialItemCount: _list.length,
itemBuilder: _buildItem,
),
),
),
);
}
}
Keeps a Dart [List] in sync with an [AnimatedList].
The [insert] and [removeAt] methods apply to both the internal list and
the animated list that belongs to [listKey].
This class only exposes as much of the Dart List API as is needed by the
sample app. More list methods are easily added, however methods that
mutate the list must make the same changes to the animated list in terms
of [AnimatedListState.insertItem] and [AnimatedList.removeItem].
class ListModel<E> {
ListModel({
@required this.listKey,
@required this.removedItemBuilder,
Iterable<E> initialItems,
}) : assert(listKey != null),
assert(removedItemBuilder != null),
_items = List<E>.from(initialItems ?? <E>[]);
final GlobalKey<AnimatedListState> listKey;
final dynamic removedItemBuilder;
final List<E> _items;
AnimatedListState get _animatedList => listKey.currentState;
void insert(int index, E item) {
_items.insert(index, item);
_animatedList.insertItem(index);
}
E removeAt(int index) {
final E removedItem = _items.removeAt(index);
if (removedItem != null) {
_animatedList.removeItem(
index,
(BuildContext context, Animation<double> animation) => removedItemBuilder(removedItem, context, animation),
);
}
return removedItem;
}
int get length => _items.length;
E operator [](int index) => _items[index];
int indexOf(E item) => _items.indexOf(item);
}
Displays its integer item as 'item N' on a Card whose color is based on
the item's value.
The text is displayed in bright green if [selected] is
true. This widget's height is based on the [animation] parameter, it
varies from 0 to 128 as the animation varies from 0.0 to 1.0.
class CardItem extends StatelessWidget {
const CardItem({
Key key,
@required this.animation,
this.onTap,
@required this.item,
this.selected: false
}) : assert(animation != null),
assert(item != null && item >= 0),
assert(selected != null),
super(key: key);
final Animation<double> animation;
final VoidCallback onTap;
final int item;
final bool selected;
@override
Widget build(BuildContext context) {
TextStyle textStyle = Theme.of(context).textTheme.headline4;
if (selected)
textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
return Padding(
padding: const EdgeInsets.all(2.0),
child: SizeTransition(
axis: Axis.vertical,
sizeFactor: animation,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onTap,
child: SizedBox(
height: 80.0,
child: Card(
color: Colors.primaries[item % Colors.primaries.length],
child: Center(
child: Text('Item $item', style: textStyle),
),
),
),
),
),
);
}
}
void main() {
runApp(AnimatedListSample());
}
```
{@end-tool}
See also:
* [SliverAnimatedList], a sliver that animates items when they are inserted
or removed from a list.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,47 @@
import '../base.dart';
class AnimatedListStateBase extends BaseWidget {
AnimatedListStateBase();
factory AnimatedListStateBase.fromJson(Map<String, dynamic> data) {
return AnimatedListStateBase();
}
@override
String get description => r"""
The state for a scrolling container that animates items when they are
inserted or removed.
When an item is inserted with [insertItem] an animation begins running. The
animation is passed to [AnimatedList.itemBuilder] whenever the item's widget
is needed.
When an item is removed with [removeItem] its animation is reversed.
The removed item's animation is passed to the [removeItem] builder
parameter.
An app that needs to insert or remove items in response to an event
can refer to the [AnimatedList]'s state with a global key:
```dart
GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
...
AnimatedList(key: listKey, ...);
...
listKey.currentState.insert(123);
```
[AnimatedList] item input handlers can also refer to their [AnimatedListState]
with the static [AnimatedList.of] method.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,39 @@
import '../base.dart';
class AnimatedModalBarrierBase extends BaseWidget {
AnimatedModalBarrierBase();
factory AnimatedModalBarrierBase.fromJson(Map<String, dynamic> data) {
return AnimatedModalBarrierBase();
}
@override
String get description => r"""
A widget that prevents the user from interacting with widgets behind itself,
and can be configured with an animated color value.
The modal barrier is the scrim that is rendered behind each route, which
generally prevents the user from interacting with the route below the
current route, and normally partially obscures such routes.
For example, when a dialog is on the screen, the page below the dialog is
usually darkened by the modal barrier.
This widget is similar to [ModalBarrier] except that it takes an animated
[color] instead of a single color.
See also:
* [ModalRoute], which uses this widget.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,79 @@
import '../base.dart';
class AnimatedOpacityBase extends BaseWidget {
AnimatedOpacityBase();
factory AnimatedOpacityBase.fromJson(Map<String, dynamic> data) {
return AnimatedOpacityBase();
}
@override
String get description => r"""
Animated version of [Opacity] which automatically transitions the child's
opacity over a given duration whenever the given opacity changes.
{@youtube 560 315 https://www.youtube.com/watch?v=QZAvjqOqiLY}
Animating an opacity is relatively expensive because it requires painting
the child into an intermediate buffer.
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.fastOutSlowIn].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_opacity.mp4}
{@tool snippet}
```dart
class LogoFade extends StatefulWidget {
@override
createState() => LogoFadeState();
}
class LogoFadeState extends State<LogoFade> {
double opacityLevel = 1.0;
void _changeOpacity() {
setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedOpacity(
opacity: opacityLevel,
duration: Duration(seconds: 3),
child: FlutterLogo(),
),
ElevatedButton(
child: Text('Fade Logo'),
onPressed: _changeOpacity,
),
],
);
}
}
```
{@end-tool}
See also:
* [AnimatedCrossFade], for fading between two children.
* [AnimatedSwitcher], for fading between many children in sequence.
* [FadeTransition], an explicitly animated version of this widget, where
an [Animation] is provided by the caller instead of being built in.
* [SliverAnimatedOpacity], for automatically transitioning a sliver's
opacity over a given duration whenever the given opacity changes.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,38 @@
import '../base.dart';
class AnimatedPaddingBase extends BaseWidget {
AnimatedPaddingBase();
factory AnimatedPaddingBase.fromJson(Map<String, dynamic> data) {
return AnimatedPaddingBase();
}
@override
String get description => r"""
Animated version of [Padding] which automatically transitions the
indentation over a given duration whenever the given inset changes.
{@youtube 560 315 https://www.youtube.com/watch?v=PY2m0fhGNz4}
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.fastOutSlowIn].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_padding.mp4}
See also:
* [AnimatedContainer], which can transition more values at once.
* [AnimatedAlign], which automatically transitions its child's
position over a given duration whenever the given
[AnimatedAlign.alignment] changes.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,37 @@
import '../base.dart';
class AnimatedPhysicalModelBase extends BaseWidget {
AnimatedPhysicalModelBase();
factory AnimatedPhysicalModelBase.fromJson(Map<String, dynamic> data) {
return AnimatedPhysicalModelBase();
}
@override
String get description => r"""
Animated version of [PhysicalModel].
The [borderRadius] and [elevation] are animated.
The [color] is animated if the [animateColor] property is set; otherwise,
the color changes immediately at the start of the animation for the other
two properties. This allows the color to be animated independently (e.g.
because it is being driven by an [AnimatedTheme]).
The [shape] is not animated.
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.fastOutSlowIn].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_physical_model.mp4}
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,54 @@
import '../base.dart';
class AnimatedPositionedBase extends BaseWidget {
AnimatedPositionedBase();
factory AnimatedPositionedBase.fromJson(Map<String, dynamic> data) {
return AnimatedPositionedBase();
}
@override
String get description => r"""
Animated version of [Positioned] which automatically transitions the child's
position over a given duration whenever the given position changes.
{@youtube 560 315 https://www.youtube.com/watch?v=hC3s2YdtWt8}
Only works if it's the child of a [Stack].
This widget is a good choice if the _size_ of the child would end up
changing as a result of this animation. If the size is intended to remain
the same, with only the _position_ changing over time, then consider
[SlideTransition] instead. [SlideTransition] only triggers a repaint each
frame of the animation, whereas [AnimatedPositioned] will trigger a relayout
as well.
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.fastOutSlowIn].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_positioned.mp4}
For the animation, you can choose a [curve] as well as a [duration] and the
widget will automatically animate to the new target position. If you require
more control over the animation (e.g. if you want to stop it mid-animation),
consider using a [PositionedTransition] instead, which takes a provided
[Animation] as an argument. While that allows you to fine-tune the animation,
it also requires more development overhead as you have to manually manage
the lifecycle of the underlying [AnimationController].
See also:
* [AnimatedPositionedDirectional], which adapts to the ambient
[Directionality] (the same as this widget, but for animating
[PositionedDirectional]).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,47 @@
import '../base.dart';
class AnimatedPositionedDirectionalBase extends BaseWidget {
AnimatedPositionedDirectionalBase();
factory AnimatedPositionedDirectionalBase.fromJson(Map<String, dynamic> data) {
return AnimatedPositionedDirectionalBase();
}
@override
String get description => r"""
Animated version of [PositionedDirectional] which automatically transitions
the child's position over a given duration whenever the given position
changes.
The ambient [Directionality] is used to determine whether [start] is to the
left or to the right.
Only works if it's the child of a [Stack].
This widget is a good choice if the _size_ of the child would end up
changing as a result of this animation. If the size is intended to remain
the same, with only the _position_ changing over time, then consider
[SlideTransition] instead. [SlideTransition] only triggers a repaint each
frame of the animation, whereas [AnimatedPositionedDirectional] will trigger
a relayout as well. ([SlideTransition] is also text-direction-aware.)
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.fastOutSlowIn].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_positioned_directional.mp4}
See also:
* [AnimatedPositioned], which specifies the widget's position visually (the
same as this widget, but for animating [Positioned]).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,64 @@
import '../base.dart';
class AnimatedSizeBase extends BaseWidget {
AnimatedSizeBase();
factory AnimatedSizeBase.fromJson(Map<String, dynamic> data) {
return AnimatedSizeBase();
}
@override
String get description => r"""
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].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,100 @@
import '../base.dart';
class AnimatedSwitcherBase extends BaseWidget {
AnimatedSwitcherBase();
factory AnimatedSwitcherBase.fromJson(Map<String, dynamic> data) {
return AnimatedSwitcherBase();
}
@override
String get description => r"""
A widget that by default does a cross-fade between a new widget and the
widget previously set on the [AnimatedSwitcher] as a child.
{@youtube 560 315 https://www.youtube.com/watch?v=2W7POjFb88g}
If they are swapped fast enough (i.e. before [duration] elapses), more than
one previous child can exist and be transitioning out while the newest one
is transitioning in.
If the "new" child is the same widget type and key as the "old" child, but
with different parameters, then [AnimatedSwitcher] will *not* do a
transition between them, since as far as the framework is concerned, they
are the same widget and the existing widget can be updated with the new
parameters. To force the transition to occur, set a [Key] on each child
widget that you wish to be considered unique (typically a [ValueKey] on the
widget data that distinguishes this child from the others).
The same key can be used for a new child as was used for an already-outgoing
child; the two will not be considered related. (For example, if a progress
indicator with key A is first shown, then an image with key B, then another
progress indicator with key A again, all in rapid succession, then the old
progress indicator and the image will be fading out while a new progress
indicator is fading in.)
The type of transition can be changed from a cross-fade to a custom
transition by setting the [transitionBuilder].
{@tool dartpad --template=stateful_widget_material}
This sample shows a counter that animates the scale of a text widget
whenever the value changes.
```dart
int _count = 0;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
transitionBuilder: (Widget child, Animation<double> animation) {
return ScaleTransition(child: child, scale: animation);
},
child: Text(
'$_count',
// This key causes the AnimatedSwitcher to interpret this as a "new"
// child each time the count changes, so that it will begin its animation
// when the count changes.
key: ValueKey<int>(_count),
style: Theme.of(context).textTheme.headline4,
),
),
ElevatedButton(
child: const Text('Increment'),
onPressed: () {
setState(() {
_count += 1;
});
},
),
],
),
);
}
```
{@end-tool}
See also:
* [AnimatedCrossFade], which only fades between two children, but also
interpolates their sizes, and is reversible.
* [AnimatedOpacity], which can be used to switch between nothingness and
a given child by fading the child in and out.
* [FadeTransition], which [AnimatedSwitcher] uses to perform the transition.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,37 @@
import '../base.dart';
class AnimatedThemeBase extends BaseWidget {
AnimatedThemeBase();
factory AnimatedThemeBase.fromJson(Map<String, dynamic> data) {
return AnimatedThemeBase();
}
@override
String get description => r"""
Animated version of [Theme] which automatically transitions the colors,
etc, over a given duration whenever the given theme changes.
Here's an illustration of what using this widget looks like, using a [curve]
of [Curves.elasticInOut].
{@animation 250 266 https://flutter.github.io/assets-for-api-docs/assets/widgets/animated_theme.mp4}
See also:
* [Theme], which [AnimatedTheme] uses to actually apply the interpolated
theme.
* [ThemeData], which describes the actual configuration of a theme.
* [MaterialApp], which includes an [AnimatedTheme] widget configured via
the [MaterialApp.theme] argument.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,164 @@
import '../base.dart';
class AnimationControllerBase extends BaseWidget {
AnimationControllerBase();
factory AnimationControllerBase.fromJson(Map<String, dynamic> data) {
return AnimationControllerBase();
}
@override
String get description => r"""
A controller for an animation.
This class lets you perform tasks such as:
* Play an animation [forward] or in [reverse], or [stop] an animation.
* Set the animation to a specific [value].
* Define the [upperBound] and [lowerBound] values of an animation.
* Create a [fling] animation effect using a physics simulation.
By default, an [AnimationController] linearly produces values that range
from 0.0 to 1.0, during a given duration. The animation controller generates
a new value whenever the device running your app is ready to display a new
frame (typically, this rate is around 60 values per second).
## Ticker providers
An [AnimationController] needs a [TickerProvider], which is configured using
the `vsync` argument on the constructor.
The [TickerProvider] interface describes a factory for [Ticker] objects. A
[Ticker] is an object that knows how to register itself with the
[SchedulerBinding] and fires a callback every frame. The
[AnimationController] class uses a [Ticker] to step through the animation
that it controls.
If an [AnimationController] is being created from a [State], then the State
can use the [TickerProviderStateMixin] and [SingleTickerProviderStateMixin]
classes to implement the [TickerProvider] interface. The
[TickerProviderStateMixin] class always works for this purpose; the
[SingleTickerProviderStateMixin] is slightly more efficient in the case of
the class only ever needing one [Ticker] (e.g. if the class creates only a
single [AnimationController] during its entire lifetime).
The widget test framework [WidgetTester] object can be used as a ticker
provider in the context of tests. In other contexts, you will have to either
pass a [TickerProvider] from a higher level (e.g. indirectly from a [State]
that mixes in [TickerProviderStateMixin]), or create a custom
[TickerProvider] subclass.
## Life cycle
An [AnimationController] should be [dispose]d when it is no longer needed.
This reduces the likelihood of leaks. When used with a [StatefulWidget], it
is common for an [AnimationController] to be created in the
[State.initState] method and then disposed in the [State.dispose] method.
## Using [Future]s with [AnimationController]
The methods that start animations return a [TickerFuture] object which
completes when the animation completes successfully, and never throws an
error; if the animation is canceled, the future never completes. This object
also has a [TickerFuture.orCancel] property which returns a future that
completes when the animation completes successfully, and completes with an
error when the animation is aborted.
This can be used to write code such as the `fadeOutAndUpdateState` method
below.
{@tool snippet}
Here is a stateful `Foo` widget. Its [State] uses the
[SingleTickerProviderStateMixin] to implement the necessary
[TickerProvider], creating its controller in the [State.initState] method
and disposing of it in the [State.dispose] method. The duration of the
controller is configured from a property in the `Foo` widget; as that
changes, the [State.didUpdateWidget] method is used to update the
controller.
```dart
class Foo extends StatefulWidget {
Foo({ Key key, this.duration }) : super(key: key);
final Duration duration;
@override
_FooState createState() => _FooState();
}
class _FooState extends State<Foo> with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this, // the SingleTickerProviderStateMixin
duration: widget.duration,
);
}
@override
void didUpdateWidget(Foo oldWidget) {
super.didUpdateWidget(oldWidget);
_controller.duration = widget.duration;
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(); // ...
}
}
```
{@end-tool}
{@tool snippet}
The following method (for a [State] subclass) drives two animation
controllers using Dart's asynchronous syntax for awaiting [Future] objects:
```dart
Future<void> fadeOutAndUpdateState() async {
try {
await fadeAnimationController.forward().orCancel;
await sizeAnimationController.forward().orCancel;
setState(() {
dismissed = true;
});
} on TickerCanceled {
// the animation got canceled, probably because we were disposed
}
}
```
{@end-tool}
The assumption in the code above is that the animation controllers are being
disposed in the [State] subclass' override of the [State.dispose] method.
Since disposing the controller cancels the animation (raising a
[TickerCanceled] exception), the code here can skip verifying whether
[State.mounted] is still true at each step. (Again, this assumes that the
controllers are created in [State.initState] and disposed in
[State.dispose], as described in the previous section.)
See also:
* [Tween], the base class for converting an [AnimationController] to a
range of values of other types.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,27 @@
import '../base.dart';
class AnimationMaxBase extends BaseWidget {
AnimationMaxBase();
factory AnimationMaxBase.fromJson(Map<String, dynamic> data) {
return AnimationMaxBase();
}
@override
String get description => r"""
An animation that tracks the maximum of two other animations.
The [value] of this animation is the maximum of the values of
[first] and [next].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,30 @@
import '../base.dart';
class AnimationMeanBase extends BaseWidget {
AnimationMeanBase();
factory AnimationMeanBase.fromJson(Map<String, dynamic> data) {
return AnimationMeanBase();
}
@override
String get description => r"""
An animation of [double]s that tracks the mean of two other animations.
The [status] of this animation is the status of the `right` animation if it is
moving, and the `left` animation otherwise.
The [value] of this animation is the [double] that represents the mean value
of the values of the `left` and `right` animations.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,27 @@
import '../base.dart';
class AnimationMinBase extends BaseWidget {
AnimationMinBase();
factory AnimationMinBase.fromJson(Map<String, dynamic> data) {
return AnimationMinBase();
}
@override
String get description => r"""
An animation that tracks the minimum of two other animations.
The [value] of this animation is the maximum of the values of
[first] and [next].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,29 @@
import '../base.dart';
class AnnotatedRegionBase extends BaseWidget {
AnnotatedRegionBase();
factory AnnotatedRegionBase.fromJson(Map<String, dynamic> data) {
return AnnotatedRegionBase();
}
@override
String get description => r"""
Annotates a region of the layer tree with a value.
See also:
* [Layer.find], for an example of how this value is retrieved.
* [AnnotatedRegionLayer], the layer pushed into the layer tree.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,44 @@
import '../base.dart';
class AnnotatedRegionLayerBase extends BaseWidget {
AnnotatedRegionLayerBase();
factory AnnotatedRegionLayerBase.fromJson(Map<String, dynamic> data) {
return AnnotatedRegionLayerBase();
}
@override
String get description => r"""
A composited layer which annotates its children with a value. Pushing this
layer to the tree is the common way of adding an annotation.
An annotation is an optional object of any type that, when attached with a
layer, can be retrieved using [Layer.find] or [Layer.findAllAnnotations]
with a position. The search process is done recursively, controlled by a
concept of being opaque to a type of annotation, explained in the document
of [Layer.findAnnotations].
When an annotation search arrives, this layer defers the same search to each
of this layer's children, respecting their opacity. Then it adds this
layer's annotation if all of the following restrictions are met:
{@template flutter.rendering.annotatedRegionLayer.restrictions}
* The target type must be identical to the annotated type `T`.
* If [size] is provided, the target position must be contained within the
rectangle formed by [size] and [offset].
{@endtemplate}
This layer is opaque to a type of annotation if any child is also opaque, or
if [opaque] is true and the layer's annotation is added.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,28 @@
import '../base.dart';
class AnnotationEntryBase extends BaseWidget {
AnnotationEntryBase();
factory AnnotationEntryBase.fromJson(Map<String, dynamic> data) {
return AnnotationEntryBase();
}
@override
String get description => r"""
Information collected for an annotation that is found in the layer tree.
See also:
* [Layer.findAnnotations], which create and use objects of this class.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,31 @@
import '../base.dart';
class AnnotationResultBase extends BaseWidget {
AnnotationResultBase();
factory AnnotationResultBase.fromJson(Map<String, dynamic> data) {
return AnnotationResultBase();
}
@override
String get description => r"""
Information collected about a list of annotations that are found in the
layer tree.
See also:
* [AnnotationEntry], which are members of this class.
* [Layer.findAllAnnotations], and [Layer.findAnnotations], which create and
use an object of this class.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,33 @@
import '../base.dart';
class AnnounceSemanticsEventBase extends BaseWidget {
AnnounceSemanticsEventBase();
factory AnnounceSemanticsEventBase.fromJson(Map<String, dynamic> data) {
return AnnounceSemanticsEventBase();
}
@override
String get description => r"""
An event for a semantic announcement.
This should be used for announcement that are not seamlessly announced by
the system as a result of a UI state change.
For example a camera application can use this method to make accessibility
announcements regarding objects in the viewfinder.
When possible, prefer using mechanisms like [Semantics] to implicitly
trigger announcements over using this event.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,141 @@
import '../base.dart';
class AppBarBase extends BaseWidget {
AppBarBase();
factory AppBarBase.fromJson(Map<String, dynamic> data) {
return AppBarBase();
}
@override
String get description => r"""
A material design app bar.
An app bar consists of a toolbar and potentially other widgets, such as a
[TabBar] and a [FlexibleSpaceBar]. App bars typically expose one or more
common [actions] with [IconButton]s which are optionally followed by a
[PopupMenuButton] for less common operations (sometimes called the "overflow
menu").
App bars are typically used in the [Scaffold.appBar] property, which places
the app bar as a fixed-height widget at the top of the screen. For a scrollable
app bar, see [SliverAppBar], which embeds an [AppBar] in a sliver for use in
a [CustomScrollView].
The AppBar displays the toolbar widgets, [leading], [title], and [actions],
above the [bottom] (if any). The [bottom] is usually used for a [TabBar]. If
a [flexibleSpace] widget is specified then it is stacked behind the toolbar
and the bottom widget. The following diagram shows where each of these slots
appears in the toolbar when the writing language is left-to-right (e.g.
English):
The [AppBar] insets its content based on the ambient [MediaQuery]'s padding,
to avoid system UI intrusions. It's taken care of by [Scaffold] when used in
the [Scaffold.appBar] property. When animating an [AppBar], unexpected
[MediaQuery] changes (as is common in [Hero] animations) may cause the content
to suddenly jump. Wrap the [AppBar] in a [MediaQuery] widget, and adjust its
padding such that the animation is smooth.
![The leading widget is in the top left, the actions are in the top right,
the title is between them. The bottom is, naturally, at the bottom, and the
flexibleSpace is behind all of them.](https://flutter.github.io/assets-for-api-docs/assets/material/app_bar.png)
If the [leading] widget is omitted, but the [AppBar] is in a [Scaffold] with
a [Drawer], then a button will be inserted to open the drawer. Otherwise, if
the nearest [Navigator] has any previous routes, a [BackButton] is inserted
instead. This behavior can be turned off by setting the [automaticallyImplyLeading]
to false. In that case a null leading widget will result in the middle/title widget
stretching to start.
{@tool dartpad --template=stateless_widget_material}
This sample shows an [AppBar] with two simple actions. The first action
opens a [SnackBar], while the second action navigates to a new page.
```dart preamble
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final SnackBar snackBar = const SnackBar(content: Text('Showing Snackbar'));
void openPage(BuildContext context) {
Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Next page'),
),
body: const Center(
child: Text(
'This is the next page',
style: TextStyle(fontSize: 24),
),
),
);
},
));
}
```
```dart
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: const Text('AppBar Demo'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_alert),
tooltip: 'Show Snackbar',
onPressed: () {
scaffoldKey.currentState.showSnackBar(snackBar);
},
),
IconButton(
icon: const Icon(Icons.navigate_next),
tooltip: 'Next page',
onPressed: () {
openPage(context);
},
),
],
),
body: const Center(
child: Text(
'This is the home page',
style: TextStyle(fontSize: 24),
),
),
);
}
```
{@end-tool}
See also:
* [Scaffold], which displays the [AppBar] in its [Scaffold.appBar] slot.
* [SliverAppBar], which uses [AppBar] to provide a flexible app bar that
can be used in a [CustomScrollView].
* [TabBar], which is typically placed in the [bottom] slot of the [AppBar]
if the screen has multiple pages arranged in tabs.
* [IconButton], which is used with [actions] to show buttons on the app bar.
* [PopupMenuButton], to show a popup menu on the app bar, via [actions].
* [FlexibleSpaceBar], which is used with [flexibleSpace] when the app bar
can expand and collapse.
* <https://material.io/design/components/app-bars-top.html>
* Cookbook: [Place a floating app bar above a list](https://flutter.dev/docs/cookbook/lists/floating-app-bar)
* See our
[AppBar Basics sample](https://flutter.dev/docs/catalog/samples/basic-app-bar)
and our advanced samples with app bars with
[tabs](https://flutter.dev/docs/catalog/samples/tabbed-app-bar) or
[custom bottom widgets](https://flutter.dev/docs/catalog/samples/app-bar-bottom).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,40 @@
import '../base.dart';
class AppBarThemeBase extends BaseWidget {
AppBarThemeBase();
factory AppBarThemeBase.fromJson(Map<String, dynamic> data) {
return AppBarThemeBase();
}
@override
String get description => r"""
Defines default property values for descendant [AppBar] widgets.
Descendant widgets obtain the current [AppBarTheme] object using
`AppBarTheme.of(context)`. Instances of [AppBarTheme] can be customized
with [AppBarTheme.copyWith].
Typically an [AppBarTheme] is specified as part of the overall [Theme] with
[ThemeData.appBarTheme].
All [AppBarTheme] properties are `null` by default. When null, the [AppBar]
will use the values from [ThemeData] if they exist, otherwise it will
provide its own defaults.
See also:
* [ThemeData], which describes the overall theme information for the
application.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,28 @@
import '../base.dart';
class ApplicationSwitcherDescriptionBase extends BaseWidget {
ApplicationSwitcherDescriptionBase();
factory ApplicationSwitcherDescriptionBase.fromJson(Map<String, dynamic> data) {
return ApplicationSwitcherDescriptionBase();
}
@override
String get description => r"""
Specifies a description of the application that is pertinent to the
embedder's application switcher (also known as "recent tasks") user
interface.
Used by [SystemChrome.setApplicationSwitcherDescription].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,61 @@
import '../base.dart';
class AspectRatioBase extends BaseWidget {
AspectRatioBase();
factory AspectRatioBase.fromJson(Map<String, dynamic> data) {
return AspectRatioBase();
}
@override
String get description => r"""
A widget that attempts to size the child to a specific aspect ratio.
The widget first tries the largest width permitted by the layout
constraints. The height of the widget is determined by applying the
given aspect ratio to the width, expressed as a ratio of width to height.
{@youtube 560 315 https://www.youtube.com/watch?v=XcnP3_mO_Ms}
For example, a 16:9 width:height aspect ratio would have a value of
16.0/9.0. If the maximum width is infinite, the initial width is determined
by applying the aspect ratio to the maximum height.
Now consider a second example, this time with an aspect ratio of 2.0 and
layout constraints that require the width to be between 0.0 and 100.0 and
the height to be between 0.0 and 100.0. We'll select a width of 100.0 (the
biggest allowed) and a height of 50.0 (to match the aspect ratio).
In that same situation, if the aspect ratio is 0.5, we'll also select a
width of 100.0 (still the biggest allowed) and we'll attempt to use a height
of 200.0. Unfortunately, that violates the constraints because the child can
be at most 100.0 pixels tall. The widget will then take that value
and apply the aspect ratio again to obtain a width of 50.0. That width is
permitted by the constraints and the child receives a width of 50.0 and a
height of 100.0. If the width were not permitted, the widget would
continue iterating through the constraints. If the widget does not
find a feasible size after consulting each constraint, the widget
will eventually select a size for the child that meets the layout
constraints but fails to meet the aspect ratio constraints.
See also:
* [Align], a widget that aligns its child within itself and optionally
sizes itself based on the child's size.
* [ConstrainedBox], a widget that imposes additional constraints on its
child.
* [UnconstrainedBox], a container that tries to let its child draw without
constraints.
* The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,26 @@
import '../base.dart';
class AssetBundleImageKeyBase extends BaseWidget {
AssetBundleImageKeyBase();
factory AssetBundleImageKeyBase.fromJson(Map<String, dynamic> data) {
return AssetBundleImageKeyBase();
}
@override
String get description => r"""
Key for the image obtained by an [AssetImage] or [ExactAssetImage].
This is used to identify the precise resource in the [imageCache].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,129 @@
import '../base.dart';
class AssetImageBase extends BaseWidget {
AssetImageBase();
factory AssetImageBase.fromJson(Map<String, dynamic> data) {
return AssetImageBase();
}
@override
String get description => r"""
Fetches an image from an [AssetBundle], having determined the exact image to
use based on the context.
Given a main asset and a set of variants, AssetImage chooses the most
appropriate asset for the current context, based on the device pixel ratio
and size given in the configuration passed to [resolve].
To show a specific image from a bundle without any asset resolution, use an
[AssetBundleImageProvider].
## Naming assets for matching with different pixel densities
Main assets are presumed to match a nominal pixel ratio of 1.0. To specify
assets targeting different pixel ratios, place the variant assets in
the application bundle under subdirectories named in the form "Nx", where
N is the nominal device pixel ratio for that asset.
For example, suppose an application wants to use an icon named
"heart.png". This icon has representations at 1.0 (the main icon), as well
as 1.5 and 2.0 pixel ratios (variants). The asset bundle should then contain
the following assets:
```
heart.png
1.5x/heart.png
2.0x/heart.png
```
On a device with a 1.0 device pixel ratio, the image chosen would be
heart.png; on a device with a 1.3 device pixel ratio, the image chosen
would be 1.5x/heart.png.
The directory level of the asset does not matter as long as the variants are
at the equivalent level; that is, the following is also a valid bundle
structure:
```
icons/heart.png
icons/1.5x/heart.png
icons/2.0x/heart.png
```
assets/icons/3.0x/heart.png would be a valid variant of
assets/icons/heart.png.
## Fetching assets
When fetching an image provided by the app itself, use the [assetName]
argument to name the asset to choose. For instance, consider the structure
above. First, the `pubspec.yaml` of the project should specify its assets in
the `flutter` section:
```yaml
flutter:
assets:
- icons/heart.png
```
Then, to fetch the image, use:
```dart
AssetImage('icons/heart.png')
```
## Assets in packages
To fetch an asset from a package, the [package] argument must be provided.
For instance, suppose the structure above is inside a package called
`my_icons`. Then to fetch the image, use:
```dart
AssetImage('icons/heart.png', package: 'my_icons')
```
Assets used by the package itself should also be fetched using the [package]
argument as above.
If the desired asset is specified in the `pubspec.yaml` of the package, it
is bundled automatically with the app. In particular, assets used by the
package itself must be specified in its `pubspec.yaml`.
A package can also choose to have assets in its 'lib/' folder that are not
specified in its `pubspec.yaml`. In this case for those images to be
bundled, the app has to specify which ones to include. For instance a
package named `fancy_backgrounds` could have:
```
lib/backgrounds/background1.png
lib/backgrounds/background2.png
lib/backgrounds/background3.png
```
To include, say the first image, the `pubspec.yaml` of the app should specify
it in the `assets` section:
```yaml
assets:
- packages/fancy_backgrounds/backgrounds/background1.png
```
The `lib/` is implied, so it should not be included in the asset path.
See also:
* [Image.asset] for a shorthand of an [Image] widget backed by [AssetImage]
when used without a scale.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,32 @@
import '../base.dart';
class AsyncSnapshotBase extends BaseWidget {
AsyncSnapshotBase();
factory AsyncSnapshotBase.fromJson(Map<String, dynamic> data) {
return AsyncSnapshotBase();
}
@override
String get description => r"""
Immutable representation of the most recent interaction with an asynchronous
computation.
See also:
* [StreamBuilder], which builds itself based on a snapshot from interacting
with a [Stream].
* [FutureBuilder], which builds itself based on a snapshot from interacting
with a [Future].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,26 @@
import '../base.dart';
class AutofillConfigurationBase extends BaseWidget {
AutofillConfigurationBase();
factory AutofillConfigurationBase.fromJson(Map<String, dynamic> data) {
return AutofillConfigurationBase();
}
@override
String get description => r"""
A collection of autofill related information that represents an [AutofillClient].
Typically used in [TextInputConfiguration.autofillConfiguration].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,145 @@
import '../base.dart';
class AutofillGroupBase extends BaseWidget {
AutofillGroupBase();
factory AutofillGroupBase.fromJson(Map<String, dynamic> data) {
return AutofillGroupBase();
}
@override
String get description => r"""
An [AutofillScope] widget that groups [AutofillClient]s together.
[AutofillClient]s that share the same closest [AutofillGroup] ancestor must
be built together, and they be will be autofilled together.
{@macro flutter.services.autofill.AutofillScope}
The [AutofillGroup] widget only knows about [AutofillClient]s registered to
it using the [AutofillGroupState.register] API. Typically, [AutofillGroup]
will not pick up [AutofillClient]s that are not mounted, for example, an
[AutofillClient] within a [Scrollable] that has never been scrolled into the
viewport. To workaround this problem, ensure clients in the same
[AutofillGroup] are built together.
The topmost [AutofillGroup] widgets (the ones that are closest to the root
widget) can be used to clean up the current autofill context when the
current autofill context is no longer relevant.
{@macro flutter.services.autofill.autofillContext}
By default, [onDisposeAction] is set to [AutofillContextAction.commit], in
which case when any of the topmost [AutofillGroup]s is being disposed, the
platform will be informed to save the user input from the current autofill
context, then the current autofill context will be destroyed, to free
resources. You can, for example, wrap a route that contains a [Form] full of
autofillable input fields in an [AutofillGroup], so the user input of the
[Form] can be saved for future autofill by the platform.
{@tool dartpad --template=stateful_widget_scaffold}
An example form with autofillable fields grouped into different
`AutofillGroup`s.
```dart
bool isSameAddress = true;
final TextEditingController shippingAddress1 = TextEditingController();
final TextEditingController shippingAddress2 = TextEditingController();
final TextEditingController billingAddress1 = TextEditingController();
final TextEditingController billingAddress2 = TextEditingController();
final TextEditingController creditCardNumber = TextEditingController();
final TextEditingController creditCardSecurityCode = TextEditingController();
final TextEditingController phoneNumber = TextEditingController();
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
const Text('Shipping address'),
// The address fields are grouped together as some platforms are
// capable of autofilling all of these fields in one go.
AutofillGroup(
child: Column(
children: <Widget>[
TextField(
controller: shippingAddress1,
autofillHints: <String>[AutofillHints.streetAddressLine1],
),
TextField(
controller: shippingAddress2,
autofillHints: <String>[AutofillHints.streetAddressLine2],
),
],
),
),
const Text('Billing address'),
Checkbox(
value: isSameAddress,
onChanged: (bool newValue) {
setState(() { isSameAddress = newValue; });
},
),
// Again the address fields are grouped together for the same reason.
if (!isSameAddress) AutofillGroup(
child: Column(
children: <Widget>[
TextField(
controller: billingAddress1,
autofillHints: <String>[AutofillHints.streetAddressLine1],
),
TextField(
controller: billingAddress2,
autofillHints: <String>[AutofillHints.streetAddressLine2],
),
],
),
),
const Text('Credit Card Information'),
// The credit card number and the security code are grouped together
// as some platforms are capable of autofilling both fields.
AutofillGroup(
child: Column(
children: <Widget>[
TextField(
controller: creditCardNumber,
autofillHints: <String>[AutofillHints.creditCardNumber],
),
TextField(
controller: creditCardSecurityCode,
autofillHints: <String>[AutofillHints.creditCardSecurityCode],
),
],
),
),
const Text('Contact Phone Number'),
// The phone number field can still be autofilled despite lacking an
// `AutofillScope`.
TextField(
controller: phoneNumber,
autofillHints: <String>[AutofillHints.telephoneNumber],
),
],
);
}
```
{@end-tool}
See also:
* [AutofillContextAction], an enum that contains predefined autofill context
clean up actions to be run when a topmost [AutofillGroup] is disposed.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,39 @@
import '../base.dart';
class AutofillGroupStateBase extends BaseWidget {
AutofillGroupStateBase();
factory AutofillGroupStateBase.fromJson(Map<String, dynamic> data) {
return AutofillGroupStateBase();
}
@override
String get description => r"""
State associated with an [AutofillGroup] widget.
{@template flutter.widgets.autofill.AutofillGroupState}
An [AutofillGroupState] can be used to register an [AutofillClient] when it
enters this [AutofillGroup] (for example, when an [EditableText] is mounted or
reparented onto the [AutofillGroup]'s subtree), and unregister an
[AutofillClient] when it exits (for example, when an [EditableText] gets
unmounted or reparented out of the [AutofillGroup]'s subtree).
The [AutofillGroupState] class also provides an [AutofillGroupState.attach]
method that can be called by [TextInputClient]s that support autofill,
instead of [TextInput.attach], to create a [TextInputConnection] to interact
with the platform's text input system.
{@endtemplate}
Typically obtained using [AutofillGroup.of].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,28 @@
import '../base.dart';
class AutofillHintsBase extends BaseWidget {
AutofillHintsBase();
factory AutofillHintsBase.fromJson(Map<String, dynamic> data) {
return AutofillHintsBase();
}
@override
String get description => r"""
A collection of commonly used autofill hint strings on different platforms.
Each hint is pre-defined on at least one supported platform. See their
documentation for their availability on each platform, and the platform
values each autofill hint corresponds to.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,34 @@
import '../base.dart';
class AutomaticKeepAliveBase extends BaseWidget {
AutomaticKeepAliveBase();
factory AutomaticKeepAliveBase.fromJson(Map<String, dynamic> data) {
return AutomaticKeepAliveBase();
}
@override
String get description => r"""
Allows subtrees to request to be kept alive in lazy lists.
This widget is like [KeepAlive] but instead of being explicitly configured,
it listens to [KeepAliveNotification] messages from the [child] and other
descendants.
The subtree is kept alive whenever there is one or more descendant that has
sent a [KeepAliveNotification] and not yet triggered its
[KeepAliveNotification.handle].
To send these notifications, consider using [AutomaticKeepAliveClientMixin].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,29 @@
import '../base.dart';
class AutomaticNotchedShapeBase extends BaseWidget {
AutomaticNotchedShapeBase();
factory AutomaticNotchedShapeBase.fromJson(Map<String, dynamic> data) {
return AutomaticNotchedShapeBase();
}
@override
String get description => r"""
A [NotchedShape] created from [ShapeBorder]s.
Two shapes can be provided. The [host] is the shape of the widget that
uses the [NotchedShape] (typically a [BottomAppBar]). The [guest] is
subtracted from the [host] to create the notch (typically to make room
for a [FloatingActionButton]).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,49 @@
import '../base.dart';
class BackButtonBase extends BaseWidget {
BackButtonBase();
factory BackButtonBase.fromJson(Map<String, dynamic> data) {
return BackButtonBase();
}
@override
String get description => r"""
A material design back button.
A [BackButton] is an [IconButton] with a "back" icon appropriate for the
current [TargetPlatform]. When pressed, the back button calls
[Navigator.maybePop] to return to the previous route unless a custom
[onPressed] callback is provided.
When deciding to display a [BackButton], consider using
`ModalRoute.of(context)?.canPop` to check whether the current route can be
popped. If that value is false (e.g., because the current route is the
initial route), the [BackButton] will not have any effect when pressed,
which could frustrate the user.
Requires one of its ancestors to be a [Material] widget.
See also:
* [AppBar], which automatically uses a [BackButton] in its
[AppBar.leading] slot when the [Scaffold] has no [Drawer] and the
current [Route] is not the [Navigator]'s first route.
* [BackButtonIcon], which is useful if you need to create a back button
that responds differently to being pressed.
* [IconButton], which is a more general widget for creating buttons with
icons.
* [CloseButton], an alternative which may be more appropriate for leaf
node pages in the navigation tree.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,35 @@
import '../base.dart';
class BackButtonIconBase extends BaseWidget {
BackButtonIconBase();
factory BackButtonIconBase.fromJson(Map<String, dynamic> data) {
return BackButtonIconBase();
}
@override
String get description => r"""
A "back" icon that's appropriate for the current [TargetPlatform].
The current platform is determined by querying for the ambient [Theme].
See also:
* [BackButton], an [IconButton] with a [BackButtonIcon] that calls
[Navigator.maybePop] to return to the previous route.
* [IconButton], which is a more general widget for creating buttons
with icons.
* [Icon], a material design icon.
* [ThemeData.platform], which specifies the current platform.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,76 @@
import '../base.dart';
class BackdropFilterBase extends BaseWidget {
BackdropFilterBase();
factory BackdropFilterBase.fromJson(Map<String, dynamic> data) {
return BackdropFilterBase();
}
@override
String get description => r"""
A widget that applies a filter to the existing painted content and then
paints [child].
The filter will be applied to all the area within its parent or ancestor
widget's clip. If there's no clip, the filter will be applied to the full
screen.
{@youtube 560 315 https://www.youtube.com/watch?v=dYRs7Q1vfYI}
{@tool snippet}
If the [BackdropFilter] needs to be applied to an area that exactly matches
its child, wraps the [BackdropFilter] with a clip widget that clips exactly
to that child.
```dart
Stack(
fit: StackFit.expand,
children: <Widget>[
Text('0' * 10000),
Center(
child: ClipRect( // <-- clips to the 200x200 [Container] below
child: BackdropFilter(
filter: ui.ImageFilter.blur(
sigmaX: 5.0,
sigmaY: 5.0,
),
child: Container(
alignment: Alignment.center,
width: 200.0,
height: 200.0,
child: Text('Hello World'),
),
),
),
),
],
)
```
{@end-tool}
This effect is relatively expensive, especially if the filter is non-local,
such as a blur.
If all you want to do is apply an [ImageFilter] to a single widget
(as opposed to applying the filter to everything _beneath_ a widget), use
[ImageFiltered] instead. For that scenario, [ImageFiltered] is both
easier to use and less expensive than [BackdropFilter].
See also:
* [ImageFiltered], which applies an [ImageFilter] to its child.
* [DecoratedBox], which draws a background under (or over) a widget.
* [Opacity], which changes the opacity of the widget itself.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,24 @@
import '../base.dart';
class BackdropFilterLayerBase extends BaseWidget {
BackdropFilterLayerBase();
factory BackdropFilterLayerBase.fromJson(Map<String, dynamic> data) {
return BackdropFilterLayerBase();
}
@override
String get description => r"""
A composited layer that applies a filter to the existing contents of the scene.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,36 @@
import '../base.dart';
class BallisticScrollActivityBase extends BaseWidget {
BallisticScrollActivityBase();
factory BallisticScrollActivityBase.fromJson(Map<String, dynamic> data) {
return BallisticScrollActivityBase();
}
@override
String get description => r"""
An activity that animates a scroll view based on a physics [Simulation].
A [BallisticScrollActivity] is typically used when the user lifts their
finger off the screen to continue the scrolling gesture with the current velocity.
[BallisticScrollActivity] is also used to restore a scroll view to a valid
scroll offset when the geometry of the scroll view changes. In these
situations, the [Simulation] typically starts with a zero velocity.
See also:
* [DrivenScrollActivity], which animates a scroll view based on a set of
animation parameters.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,32 @@
import '../base.dart';
class BannerBase extends BaseWidget {
BannerBase();
factory BannerBase.fromJson(Map<String, dynamic> data) {
return BannerBase();
}
@override
String get description => r"""
Displays a diagonal message above the corner of another widget.
Useful for showing the execution mode of an app (e.g., that asserts are
enabled.)
See also:
* [CheckedModeBanner], which the [WidgetsApp] widget includes by default in
debug mode, to show a banner that says "DEBUG".
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,24 @@
import '../base.dart';
class BannerPainterBase extends BaseWidget {
BannerPainterBase();
factory BannerPainterBase.fromJson(Map<String, dynamic> data) {
return BannerPainterBase();
}
@override
String get description => r"""
Paints a [Banner].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,38 @@
import '../base.dart';
class BaselineBase extends BaseWidget {
BaselineBase();
factory BaselineBase.fromJson(Map<String, dynamic> data) {
return BaselineBase();
}
@override
String get description => r"""
A widget that positions its child according to the child's baseline.
This widget shifts the child down such that the child's baseline (or the
bottom of the child, if the child has no baseline) is [baseline]
logical pixels below the top of this box, then sizes this box to
contain the child. If [baseline] is less than the distance from
the top of the child to the baseline of the child, then the child
is top-aligned instead.
See also:
* [Align], a widget that aligns its child within itself and optionally
sizes itself based on the child's size.
* [Center], a widget that centers its child within itself.
* The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,40 @@
import '../base.dart';
class BasicMessageChannelBase extends BaseWidget {
BasicMessageChannelBase();
factory BasicMessageChannelBase.fromJson(Map<String, dynamic> data) {
return BasicMessageChannelBase();
}
@override
String get description => r"""
A named channel for communicating with platform plugins using asynchronous
message passing.
Messages are encoded into binary before being sent, and binary messages
received are decoded into Dart values. The [MessageCodec] used must be
compatible with the one used by the platform plugin. This can be achieved
by creating a basic message channel counterpart of this channel on the
platform side. The Dart type of messages sent and received is [T],
but only the values supported by the specified [MessageCodec] can be used.
The use of unsupported values should be considered programming errors, and
will result in exceptions being thrown. The null message is supported
for all codecs.
The logical identity of the channel is given by its name. Identically named
channels will interfere with each other's communication.
See: <https://flutter.dev/platform-channels/>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,30 @@
import '../base.dart';
class BeveledRectangleBorderBase extends BaseWidget {
BeveledRectangleBorderBase();
factory BeveledRectangleBorderBase.fromJson(Map<String, dynamic> data) {
return BeveledRectangleBorderBase();
}
@override
String get description => r"""
A rectangular border with flattened or "beveled" corners.
The line segments that connect the rectangle's four sides will
begin and at locations offset by the corresponding border radius,
but not farther than the side's center. If all the border radii
exceed the sides' half widths/heights the resulting shape is
diamond made by connecting the centers of the sides.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,31 @@
import '../base.dart';
class BinaryCodecBase extends BaseWidget {
BinaryCodecBase();
factory BinaryCodecBase.fromJson(Map<String, dynamic> data) {
return BinaryCodecBase();
}
@override
String get description => r"""
[MessageCodec] with unencoded binary messages represented using [ByteData].
On Android, messages will be represented using `java.nio.ByteBuffer`.
On iOS, messages will be represented using `NSData`.
When sending outgoing messages from Android, be sure to use direct `ByteBuffer`
as opposed to indirect. The `wrap()` API provides indirect buffers by default
and you will get empty `ByteData` objects in Dart.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,38 @@
import '../base.dart';
class BinaryMessagesBase extends BaseWidget {
BinaryMessagesBase();
factory BinaryMessagesBase.fromJson(Map<String, dynamic> data) {
return BinaryMessagesBase();
}
@override
String get description => r"""
Sends binary messages to and receives binary messages from platform plugins.
This class has been deprecated in favor of [defaultBinaryMessenger]. New
code should not use [BinaryMessages].
See also:
* [BinaryMessenger], the interface which has replaced this class.
* [BasicMessageChannel], which provides basic messaging services similar to
`BinaryMessages`, but with pluggable message codecs in support of sending
strings or semi-structured messages.
* [MethodChannel], which provides platform communication using asynchronous
method calls.
* [EventChannel], which provides platform communication using event streams.
* <https://flutter.dev/platform-channels/>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,24 @@
import '../base.dart';
class BitFieldBase extends BaseWidget {
BitFieldBase();
factory BitFieldBase.fromJson(Map<String, dynamic> data) {
return BitFieldBase();
}
@override
String get description => r"""
The dart:io implementation of [bitfield.Bitfield].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,24 @@
import '../base.dart';
class BlacklistingTextInputFormatterBase extends BaseWidget {
BlacklistingTextInputFormatterBase();
factory BlacklistingTextInputFormatterBase.fromJson(Map<String, dynamic> data) {
return BlacklistingTextInputFormatterBase();
}
@override
String get description => r"""
Old name for [FilteringTextInputFormatter.deny].
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,35 @@
import '../base.dart';
class BlockSemanticsBase extends BaseWidget {
BlockSemanticsBase();
factory BlockSemanticsBase.fromJson(Map<String, dynamic> data) {
return BlockSemanticsBase();
}
@override
String get description => r"""
A widget that drops the semantics of all widget that were painted before it
in the same semantic container.
This is useful to hide widgets from accessibility tools that are painted
behind a certain widget, e.g. an alert should usually disallow interaction
with any widget located "behind" the alert (even when they are still
partially visible). Similarly, an open [Drawer] blocks interactions with
any widget outside the drawer.
See also:
* [ExcludeSemantics] which drops all semantics of its descendants.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,84 @@
import '../base.dart';
class BorderBase extends BaseWidget {
BorderBase();
factory BorderBase.fromJson(Map<String, dynamic> data) {
return BorderBase();
}
@override
String get description => r"""
A border of a box, comprised of four sides: top, right, bottom, left.
The sides are represented by [BorderSide] objects.
{@tool snippet}
All four borders the same, two-pixel wide solid white:
```dart
Border.all(width: 2.0, color: const Color(0xFFFFFFFF))
```
{@end-tool}
{@tool snippet}
The border for a material design divider:
```dart
Border(bottom: BorderSide(color: Theme.of(context).dividerColor))
```
{@end-tool}
{@tool snippet}
A 1990s-era "OK" button:
```dart
Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
left: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
right: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
bottom: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
),
),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
decoration: const BoxDecoration(
border: Border(
top: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
left: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
right: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
bottom: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
),
color: Color(0xFFBFBFBF),
),
child: const Text(
'OK',
textAlign: TextAlign.center,
style: TextStyle(color: Color(0xFF000000))
),
),
)
```
{@end-tool}
See also:
* [BoxDecoration], which uses this class to describe its edge decoration.
* [BorderSide], which is used to describe each side of the box.
* [Theme], from the material layer, which can be queried to obtain appropriate colors
to use for borders in a material app, as shown in the "divider" sample above.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,42 @@
import '../base.dart';
class BorderDirectionalBase extends BaseWidget {
BorderDirectionalBase();
factory BorderDirectionalBase.fromJson(Map<String, dynamic> data) {
return BorderDirectionalBase();
}
@override
String get description => r"""
A border of a box, comprised of four sides, the lateral sides of which
flip over based on the reading direction.
The lateral sides are called [start] and [end]. When painted in
left-to-right environments, the [start] side will be painted on the left and
the [end] side on the right; in right-to-left environments, it is the
reverse. The other two sides are [top] and [bottom].
The sides are represented by [BorderSide] objects.
If the [start] and [end] sides are the same, then it is slightly more
efficient to use a [Border] object rather than a [BorderDirectional] object.
See also:
* [BoxDecoration], which uses this class to describe its edge decoration.
* [BorderSide], which is used to describe each side of the box.
* [Theme], from the material layer, which can be queried to obtain appropriate colors
to use for borders in a material app, as shown in the "divider" sample above.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,32 @@
import '../base.dart';
class BorderRadiusBase extends BaseWidget {
BorderRadiusBase();
factory BorderRadiusBase.fromJson(Map<String, dynamic> data) {
return BorderRadiusBase();
}
@override
String get description => r"""
An immutable set of radii for each corner of a rectangle.
Used by [BoxDecoration] when the shape is a [BoxShape.rectangle].
The [BorderRadius] class specifies offsets in terms of visual corners, e.g.
[topLeft]. These values are not affected by the [TextDirection]. To support
both left-to-right and right-to-left layouts, consider using
[BorderRadiusDirectional], which is expressed in terms that are relative to
a [TextDirection] (typically obtained from the ambient [Directionality]).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,35 @@
import '../base.dart';
class BorderRadiusDirectionalBase extends BaseWidget {
BorderRadiusDirectionalBase();
factory BorderRadiusDirectionalBase.fromJson(Map<String, dynamic> data) {
return BorderRadiusDirectionalBase();
}
@override
String get description => r"""
An immutable set of radii for each corner of a rectangle, but with the
corners specified in a manner dependent on the writing direction.
This can be used to specify a corner radius on the leading or trailing edge
of a box, so that it flips to the other side when the text alignment flips
(e.g. being on the top right in English text but the top left in Arabic
text).
See also:
* [BorderRadius], a variant that uses physical labels (`topLeft` and
`topRight` instead of `topStart` and `topEnd`).
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,29 @@
import '../base.dart';
class BorderRadiusTweenBase extends BaseWidget {
BorderRadiusTweenBase();
factory BorderRadiusTweenBase.fromJson(Map<String, dynamic> data) {
return BorderRadiusTweenBase();
}
@override
String get description => r"""
An interpolation between two [BorderRadius]s.
This class specializes the interpolation of [Tween<BorderRadius>] to use
[BorderRadius.lerp].
See [Tween] for a discussion on how to use interpolation objects.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,59 @@
import '../base.dart';
class BorderSideBase extends BaseWidget {
BorderSideBase();
factory BorderSideBase.fromJson(Map<String, dynamic> data) {
return BorderSideBase();
}
@override
String get description => r"""
A side of a border of a box.
A [Border] consists of four [BorderSide] objects: [Border.top],
[Border.left], [Border.right], and [Border.bottom].
Note that setting [BorderSide.width] to 0.0 will result in hairline
rendering. A more involved explanation is present in [BorderSide.width].
{@tool snippet}
This sample shows how [BorderSide] objects can be used in a [Container], via
a [BoxDecoration] and a [Border], to decorate some [Text]. In this example,
the text has a thick bar above it that is light blue, and a thick bar below
it that is a darker shade of blue.
```dart
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 16.0, color: Colors.lightBlue.shade50),
bottom: BorderSide(width: 16.0, color: Colors.lightBlue.shade900),
),
),
child: Text('Flutter in the sky', textAlign: TextAlign.center),
)
```
{@end-tool}
See also:
* [Border], which uses [BorderSide] objects to represent its sides.
* [BoxDecoration], which optionally takes a [Border] object.
* [TableBorder], which is similar to [Border] but has two more sides
([TableBorder.horizontalInside] and [TableBorder.verticalInside]), both
of which are also [BorderSide] objects.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,29 @@
import '../base.dart';
class BorderTweenBase extends BaseWidget {
BorderTweenBase();
factory BorderTweenBase.fromJson(Map<String, dynamic> data) {
return BorderTweenBase();
}
@override
String get description => r"""
An interpolation between two [Border]s.
This class specializes the interpolation of [Tween<Border>] to use
[Border.lerp].
See [Tween] for a discussion on how to use interpolation objects.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,46 @@
import '../base.dart';
class BottomAppBarBase extends BaseWidget {
BottomAppBarBase();
factory BottomAppBarBase.fromJson(Map<String, dynamic> data) {
return BottomAppBarBase();
}
@override
String get description => r"""
A container that is typically used with [Scaffold.bottomNavigationBar], and
can have a notch along the top that makes room for an overlapping
[FloatingActionButton].
Typically used with a [Scaffold] and a [FloatingActionButton].
{@tool snippet}
```dart
Scaffold(
bottomNavigationBar: BottomAppBar(
color: Colors.white,
child: bottomAppBarContents,
),
floatingActionButton: FloatingActionButton(onPressed: null),
)
```
{@end-tool}
See also:
* [NotchedShape] which calculates the notch for a notched [BottomAppBar].
* [FloatingActionButton] which the [BottomAppBar] makes a notch for.
* [AppBar] for a toolbar that is shown at the top of the screen.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,39 @@
import '../base.dart';
class BottomAppBarThemeBase extends BaseWidget {
BottomAppBarThemeBase();
factory BottomAppBarThemeBase.fromJson(Map<String, dynamic> data) {
return BottomAppBarThemeBase();
}
@override
String get description => r"""
Defines default property values for descendant [BottomAppBar] widgets.
Descendant widgets obtain the current [BottomAppBarTheme] object using
`BottomAppBarTheme.of(context)`. Instances of [BottomAppBarTheme] can be
customized with [BottomAppBarTheme.copyWith].
Typically a [BottomAppBarTheme] is specified as part of the overall [Theme]
with [ThemeData.bottomAppBarTheme].
All [BottomAppBarTheme] properties are `null` by default. When null, the
[BottomAppBar] constructor provides defaults.
See also:
* [ThemeData], which describes the overall theme information for the
application.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,124 @@
import '../base.dart';
class BottomNavigationBarBase extends BaseWidget {
BottomNavigationBarBase();
factory BottomNavigationBarBase.fromJson(Map<String, dynamic> data) {
return BottomNavigationBarBase();
}
@override
String get description => r"""
A material widget that's displayed at the bottom of an app for selecting
among a small number of views, typically between three and five.
The bottom navigation bar consists of multiple items in the form of
text labels, icons, or both, laid out on top of a piece of material. It
provides quick navigation between the top-level views of an app. For larger
screens, side navigation may be a better fit.
A bottom navigation bar is usually used in conjunction with a [Scaffold],
where it is provided as the [Scaffold.bottomNavigationBar] argument.
The bottom navigation bar's [type] changes how its [items] are displayed.
If not specified, then it's automatically set to
[BottomNavigationBarType.fixed] when there are less than four items, and
[BottomNavigationBarType.shifting] otherwise.
* [BottomNavigationBarType.fixed], the default when there are less than
four [items]. The selected item is rendered with the
[selectedItemColor] if it's non-null, otherwise the theme's
[ThemeData.primaryColor] is used. If [backgroundColor] is null, The
navigation bar's background color defaults to the [Material] background
color, [ThemeData.canvasColor] (essentially opaque white).
* [BottomNavigationBarType.shifting], the default when there are four
or more [items]. If [selectedItemColor] is null, all items are rendered
in white. The navigation bar's background color is the same as the
[BottomNavigationBarItem.backgroundColor] of the selected item. In this
case it's assumed that each item will have a different background color
and that background color will contrast well with white.
{@tool dartpad --template=stateful_widget_material}
This example shows a [BottomNavigationBar] as it is used within a [Scaffold]
widget. The [BottomNavigationBar] has three [BottomNavigationBarItem]
widgets and the [currentIndex] is set to index 0. The selected item is
amber. The `_onItemTapped` function changes the selected item's index
and displays a corresponding message in the center of the [Scaffold].
![A scaffold with a bottom navigation bar containing three bottom navigation
bar items. The first one is selected.](https://flutter.github.io/assets-for-api-docs/assets/material/bottom_navigation_bar.png)
```dart
int _selectedIndex = 0;
static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
```
{@end-tool}
See also:
* [BottomNavigationBarItem]
* [Scaffold]
* <https://material.io/design/components/bottom-navigation.html>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,35 @@
import '../base.dart';
class BottomNavigationBarItemBase extends BaseWidget {
BottomNavigationBarItemBase();
factory BottomNavigationBarItemBase.fromJson(Map<String, dynamic> data) {
return BottomNavigationBarItemBase();
}
@override
String get description => r"""
An interactive button within either material's [BottomNavigationBar]
or the iOS themed [CupertinoTabBar] with an icon and title.
This class is rarely used in isolation. It is typically embedded in one of
the bottom navigation widgets above.
See also:
* [BottomNavigationBar]
* <https://material.io/design/components/bottom-navigation.html>
* [CupertinoTabBar]
* <https://developer.apple.com/ios/human-interface-guidelines/bars/tab-bars>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,38 @@
import '../base.dart';
class BottomNavigationBarThemeBase extends BaseWidget {
BottomNavigationBarThemeBase();
factory BottomNavigationBarThemeBase.fromJson(Map<String, dynamic> data) {
return BottomNavigationBarThemeBase();
}
@override
String get description => r"""
Applies a bottom navigation bar theme to descendant [BottomNavigationBar]
widgets.
Descendant widgets obtain the current theme's [BottomNavigationBarTheme]
object using [BottomNavigationBarTheme.of]. When a widget uses
[BottomNavigationBarTheme.of], it is automatically rebuilt if the theme
later changes.
A bottom navigation theme can be specified as part of the overall Material
theme using [ThemeData.bottomNavigationBarTheme].
See also:
* [BottomNavigationBarThemeData], which describes the actual configuration
of a bottom navigation bar theme.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,41 @@
import '../base.dart';
class BottomNavigationBarThemeDataBase extends BaseWidget {
BottomNavigationBarThemeDataBase();
factory BottomNavigationBarThemeDataBase.fromJson(Map<String, dynamic> data) {
return BottomNavigationBarThemeDataBase();
}
@override
String get description => r"""
Defines default property values for descendant [BottomNavigationBar]
widgets.
Descendant widgets obtain the current [BottomNavigationBarThemeData] object
using `BottomNavigationBarTheme.of(context)`. Instances of
[BottomNavigationBarThemeData] can be customized with
[BottomNavigationBarThemeData.copyWith].
Typically a [BottomNavigationBarThemeData] is specified as part of the
overall [Theme] with [ThemeData.bottomNavigationBarTheme].
All [BottomNavigationBarThemeData] properties are `null` by default. When
null, the [BottomNavigationBar]'s build method provides defaults.
See also:
* [ThemeData], which describes the overall theme information for the
application.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,50 @@
import '../base.dart';
class BottomSheetBase extends BaseWidget {
BottomSheetBase();
factory BottomSheetBase.fromJson(Map<String, dynamic> data) {
return BottomSheetBase();
}
@override
String get description => r"""
A material design bottom sheet.
There are two kinds of bottom sheets in material design:
* _Persistent_. A persistent bottom sheet shows information that
supplements the primary content of the app. A persistent bottom sheet
remains visible even when the user interacts with other parts of the app.
Persistent bottom sheets can be created and displayed with the
[ScaffoldState.showBottomSheet] function or by specifying the
[Scaffold.bottomSheet] constructor parameter.
* _Modal_. A modal bottom sheet is an alternative to a menu or a dialog and
prevents the user from interacting with the rest of the app. Modal bottom
sheets can be created and displayed with the [showModalBottomSheet]
function.
The [BottomSheet] widget itself is rarely used directly. Instead, prefer to
create a persistent bottom sheet with [ScaffoldState.showBottomSheet] or
[Scaffold.bottomSheet], and a modal bottom sheet with [showModalBottomSheet].
See also:
* [showBottomSheet] and [ScaffoldState.showBottomSheet], for showing
non-modal "persistent" bottom sheets.
* [showModalBottomSheet], which can be used to display a modal bottom
sheet.
* <https://material.io/design/components/sheets-bottom.html>
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,40 @@
import '../base.dart';
class BottomSheetThemeDataBase extends BaseWidget {
BottomSheetThemeDataBase();
factory BottomSheetThemeDataBase.fromJson(Map<String, dynamic> data) {
return BottomSheetThemeDataBase();
}
@override
String get description => r"""
Defines default property values for [BottomSheet]'s [Material].
Descendant widgets obtain the current [BottomSheetThemeData] object
using `Theme.of(context).bottomSheetTheme`. Instances of
[BottomSheetThemeData] can be customized with
[BottomSheetThemeData.copyWith].
Typically a [BottomSheetThemeData] is specified as part of the
overall [Theme] with [ThemeData.bottomSheetTheme].
All [BottomSheetThemeData] properties are `null` by default.
When null, the [BottomSheet] will provide its own defaults.
See also:
* [ThemeData], which describes the overall theme information for the
application.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,48 @@
import '../base.dart';
class BouncingScrollPhysicsBase extends BaseWidget {
BouncingScrollPhysicsBase();
factory BouncingScrollPhysicsBase.fromJson(Map<String, dynamic> data) {
return BouncingScrollPhysicsBase();
}
@override
String get description => r"""
Scroll physics for environments that allow the scroll offset to go beyond
the bounds of the content, but then bounce the content back to the edge of
those bounds.
This is the behavior typically seen on iOS.
[BouncingScrollPhysics] by itself will not create an overscroll effect if
the contents of the scroll view do not extend beyond the size of the
viewport. To create the overscroll and bounce effect regardless of the
length of your scroll view, combine with [AlwaysScrollableScrollPhysics].
{@tool snippet}
```dart
BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics())
```
{@end-tool}
See also:
* [ScrollConfiguration], which uses this to provide the default
scroll behavior on iOS.
* [ClampingScrollPhysics], which is the analogous physics for Android's
clamping behavior.
* [ScrollPhysics], for more examples of combining [ScrollPhysics] objects
of different types to get the desired scroll physics.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}
@@ -0,0 +1,28 @@
import '../base.dart';
class BouncingScrollSimulationBase extends BaseWidget {
BouncingScrollSimulationBase();
factory BouncingScrollSimulationBase.fromJson(Map<String, dynamic> data) {
return BouncingScrollSimulationBase();
}
@override
String get description => r"""
An implementation of scroll physics that matches iOS.
See also:
* [ClampingScrollSimulation], which implements Android scroll physics.
""";
@override
Map<String, dynamic> toJson() {
return {};
}
@override
Widget render(BuildContext context) {
return Container();
}
}

Some files were not shown because too many files have changed in this diff Show More