Commit 79364f0a authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add Container.align and Container.position (#5128)

These let you add Align widget to the inside or outside of a container.
Several customers have asked for these properties.

Fixes #4950
parent 534097ff
......@@ -284,11 +284,9 @@ class CardCollectionState extends State<CardCollection> {
flexibleSpace: new Container(
padding: const EdgeInsets.only(left: 72.0),
height: 128.0,
child: new Align(
alignment: const FractionalOffset(0.0, 0.75),
align: const FractionalOffset(0.0, 0.75),
child: new Text('Swipe Away: ${_cardModels.length}', style: Theme.of(context).primaryTextTheme.title)
)
)
);
}
......
......@@ -166,20 +166,16 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new Align(
alignment: FractionalOffset.bottomLeft,
align: FractionalOffset.bottomLeft,
child: new Text('Event name', style: theme.textTheme.display2)
)
),
new Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new Align(
alignment: FractionalOffset.bottomLeft,
align: FractionalOffset.bottomLeft,
child: new Text('Location', style: theme.textTheme.title.copyWith(color: Colors.black54))
)
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
......
......@@ -331,7 +331,7 @@ class _RecipePageState extends State<_RecipePage> {
const double fabHalfSize = 28.0; // TODO(mpcomplete): needs to adapt to screen size
return new Hero(
tag: config.recipe.imagePath,
child: new DecoratedBox(
child: new Container(
decoration: new BoxDecoration(
backgroundColor: Theme.of(context).canvasColor,
backgroundImage: new BackgroundImage(
......@@ -340,8 +340,7 @@ class _RecipePageState extends State<_RecipePage> {
fit: fullWidth ? ImageFit.fitWidth : ImageFit.cover
)
),
child: new Align(
alignment: FractionalOffset.bottomCenter,
align: FractionalOffset.bottomCenter,
child: new Block(
children: <Widget>[
new Padding(
......@@ -368,7 +367,6 @@ class _RecipePageState extends State<_RecipePage> {
]
)
)
)
);
}
......
......@@ -71,11 +71,9 @@ class GalleryHomeState extends State<GalleryHome> {
new Container(
height: 48.0,
padding: const EdgeInsets.only(left: 16.0),
child: new Align(
alignment: FractionalOffset.centerLeft,
align: FractionalOffset.centerLeft,
child: new Text(galleryItem.category, style: headerStyle)
)
)
);
category = galleryItem.category;
}
......
......@@ -406,8 +406,7 @@ class DataTable extends StatelessWidget {
label = new Container(
padding: padding,
height: _kHeadingRowHeight,
child: new Align(
alignment: new FractionalOffset(numeric ? 1.0 : 0.0, 0.5), // TODO(ianh): RTL for non-numeric
align: new FractionalOffset(numeric ? 1.0 : 0.0, 0.5), // TODO(ianh): RTL for non-numeric
child: new AnimatedDefaultTextStyle(
style: new TextStyle(
// TODO(ianh): font family should be Roboto; see https://github.com/flutter/flutter/issues/3116
......@@ -421,7 +420,6 @@ class DataTable extends StatelessWidget {
duration: _kSortArrowAnimationDuration,
child: label
)
)
);
if (tooltip != null) {
label = new Tooltip(
......@@ -458,8 +456,7 @@ class DataTable extends StatelessWidget {
label = new Container(
padding: padding,
height: _kDataRowHeight,
child: new Align(
alignment: new FractionalOffset(numeric ? 1.0 : 0.0, 0.5), // TODO(ianh): RTL for non-numeric
align: new FractionalOffset(numeric ? 1.0 : 0.0, 0.5), // TODO(ianh): RTL for non-numeric
child: new DefaultTextStyle(
style: new TextStyle(
// TODO(ianh): font family should be Roboto; see https://github.com/flutter/flutter/issues/3116
......@@ -476,7 +473,6 @@ class DataTable extends StatelessWidget {
child: new DropDownButtonHideUnderline(child: label)
)
)
)
);
if (onTap != null) {
label = new InkWell(
......
......@@ -337,10 +337,8 @@ class DropDownMenuItem<T> extends StatelessWidget {
Widget build(BuildContext context) {
return new Container(
height: _kMenuItemHeight,
child: new Align(
alignment: FractionalOffset.centerLeft,
align: FractionalOffset.centerLeft,
child: child
)
);
}
}
......
......@@ -146,10 +146,9 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
);
final bool effectiveCenterTitle = _getEffectiveCenterTitle(theme);
final FractionalOffset titleAlignment = effectiveCenterTitle ? FractionalOffset.bottomCenter : FractionalOffset.bottomLeft;
children.add(new Padding(
children.add(new Container(
padding: new EdgeInsets.only(left: effectiveCenterTitle ? 0.0 : 72.0, bottom: 14.0),
child: new Align(
alignment: new Tween<FractionalOffset>(
align: new Tween<FractionalOffset>(
begin: new FractionalOffset(0.0, yAlignStart),
end: new FractionalOffset(0.0, yAlignEnd)
).evaluate(scaleAndAlignCurve),
......@@ -161,7 +160,6 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
child: new DefaultTextStyle(style: titleStyle, child: config.title)
)
)
)
));
}
}
......
......@@ -154,10 +154,8 @@ class ListItem extends StatelessWidget {
children.add(new Container(
margin: const EdgeInsets.only(right: 16.0),
width: 40.0,
child: new Align(
alignment: FractionalOffset.centerLeft,
align: FractionalOffset.centerLeft,
child: leading
)
));
}
......@@ -188,10 +186,8 @@ class ListItem extends StatelessWidget {
if (trailing != null) {
children.add(new Container(
margin: const EdgeInsets.only(left: 16.0),
child: new Align(
alignment: FractionalOffset.centerRight,
align: FractionalOffset.centerRight,
child: trailing
)
));
}
......
......@@ -370,8 +370,7 @@ class RefreshIndicatorState extends State<RefreshIndicator> {
padding: _isIndicatorAtTop
? new EdgeInsets.only(top: config.displacement)
: new EdgeInsets.only(bottom: config.displacement),
child: new Align(
alignment: _isIndicatorAtTop
align: _isIndicatorAtTop
? FractionalOffset.bottomCenter
: FractionalOffset.topCenter,
child: new ScaleTransition(
......@@ -390,7 +389,6 @@ class RefreshIndicatorState extends State<RefreshIndicator> {
)
)
)
)
]
)
);
......
......@@ -74,6 +74,7 @@ class Container extends StatelessWidget {
/// Creates a widget that combines common painting, positioning, and sizing widgets.
Container({
Key key,
this.align,
this.padding,
this.decoration,
this.foregroundDecoration,
......@@ -99,6 +100,12 @@ class Container extends StatelessWidget {
/// If null, the container will expand to fill all available space in its parent.
final Widget child;
/// Align the child within the container.
///
/// If non-null, the container will expand to fill its parent and position its
/// child within itself according to the given value.
final FractionalOffset align;
/// Empty space to inscribe inside the decoration.
final EdgeInsets padding;
......@@ -133,6 +140,9 @@ class Container extends StatelessWidget {
if (child == null && (constraints == null || !constraints.isTight))
current = new ConstrainedBox(constraints: const BoxConstraints.expand());
if (align != null)
current = new Align(alignment: align, child: current);
EdgeInsets effectivePadding = _paddingIncludingDecoration;
if (effectivePadding != null)
current = new Padding(padding: effectivePadding, child: current);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment