Commit 1867b58c authored by Ian Hickson's avatar Ian Hickson

Merge pull request #792 from Hixie/flex-part3

Add `Row` and `Column` widgets so you don't have to use Flex.
parents 75633c8c 3d37e787
...@@ -46,10 +46,9 @@ very commonly used: ...@@ -46,10 +46,9 @@ very commonly used:
* `Text`: The `Text` widget lets you create a run of styled text within your * `Text`: The `Text` widget lets you create a run of styled text within your
application. application.
* `Flex`: The `Flex` widget lets you create flexible layouts in both the * `Row`, `Column`: These flex widgets let you create flexible layouts
horizontal and vertical direction. Its design is based on the web's flexbox in both the horizontal (`Row`) and vertical (`Column`) directions.
layout model. You can also use the simpler `Block` widget to create vertical Its design is based on the web's flexbox layout model.
layouts of inflexible items.
* `Container`: The `Container` widget lets you create rectangular visual * `Container`: The `Container` widget lets you create rectangular visual
element. A container can be decorated with a `BoxDecoration`, such as a element. A container can be decorated with a `BoxDecoration`, such as a
...@@ -75,7 +74,7 @@ class MyToolBar extends Component { ...@@ -75,7 +74,7 @@ class MyToolBar extends Component {
), ),
height: 56.0, height: 56.0,
padding: const EdgeDims.symmetric(horizontal: 8.0), padding: const EdgeDims.symmetric(horizontal: 8.0),
child: new Flex([ child: new Row([
new NetworkImage(src: 'menu.png', width: 25.0, height: 25.0), new NetworkImage(src: 'menu.png', width: 25.0, height: 25.0),
new Flexible(child: new Text('My awesome toolbar')), new Flexible(child: new Text('My awesome toolbar')),
new NetworkImage(src: 'search.png', width: 25.0, height: 25.0), new NetworkImage(src: 'search.png', width: 25.0, height: 25.0),
...@@ -85,14 +84,15 @@ class MyToolBar extends Component { ...@@ -85,14 +84,15 @@ class MyToolBar extends Component {
} }
``` ```
The `MyToolBar` component creates a cyan `Container` with a height of 56 The `MyToolBar` component creates a cyan `Container` with a height of
device-independent pixels with an internal padding of 8 pixels, both on the 56 device-independent pixels with an internal padding of 8 pixels,
left and the right. Inside the container, `MyToolBar` uses a `Flex` layout both on the left and the right. Inside the container, `MyToolBar` uses
in the (default) horizontal direction. The middle child, the `Text` widget, is a `Row` layout. The middle child, the `Text` widget, is marked as
marked as `Flexible`, which means it expands to fill any remaining available `Flexible`, which means it expands to fill any remaining available
space that hasn't been consumed by the inflexible children. You can have space that hasn't been consumed by the inflexible children. You can
multiple `Flexible` children and determine the ratio in which they consume the have multiple `Flexible` children and determine the ratio in which
available space using the `flex` argument to `Flexible`. they consume the available space using the `flex` argument to
`Flexible`.
To use this component, we simply create an instance of `MyToolBar` in a `build` To use this component, we simply create an instance of `MyToolBar` in a `build`
function: function:
...@@ -207,7 +207,7 @@ button: ...@@ -207,7 +207,7 @@ button:
Widget build() { Widget build() {
return new MyButton( return new MyButton(
child: new ShrinkWrapWidth( child: new ShrinkWrapWidth(
child: new Flex([ child: new Row([
new NetworkImage(src: 'thumbs-up.png', width: 25.0, height: 25.0), new NetworkImage(src: 'thumbs-up.png', width: 25.0, height: 25.0),
new Container( new Container(
padding: const EdgeDims.only(left: 10.0), padding: const EdgeDims.only(left: 10.0),
...@@ -272,7 +272,7 @@ class MyDialog extends StatefulComponent { ...@@ -272,7 +272,7 @@ class MyDialog extends StatefulComponent {
} }
Widget build() { Widget build() {
return new Flex([ return new Row([
new MyCheckbox( new MyCheckbox(
value: _checkboxValue, value: _checkboxValue,
onChanged: _handleCheckboxValueChanged onChanged: _handleCheckboxValueChanged
......
...@@ -476,6 +476,24 @@ class Flex extends MultiChildRenderObjectWrapper { ...@@ -476,6 +476,24 @@ class Flex extends MultiChildRenderObjectWrapper {
} }
class Row extends Flex {
Row(List<Widget> children, {
Key key,
justifyContent: FlexJustifyContent.start,
alignItems: FlexAlignItems.center,
textBaseline
}) : super(children, key: key, direction: FlexDirection.horizontal, justifyContent: justifyContent, alignItems: alignItems);
}
class Column extends Flex {
Column(List<Widget> children, {
Key key,
justifyContent: FlexJustifyContent.start,
alignItems: FlexAlignItems.center,
textBaseline
}) : super(children, key: key, direction: FlexDirection.vertical, justifyContent: justifyContent, alignItems: alignItems);
}
class Flexible extends ParentDataNode { class Flexible extends ParentDataNode {
Flexible({ Key key, int flex: 1, Widget child }) Flexible({ Key key, int flex: 1, Widget child })
: super(child, new FlexBoxParentData()..flex = flex, key: key); : super(child, new FlexBoxParentData()..flex = flex, key: key);
......
...@@ -80,7 +80,7 @@ class Dialog extends Component { ...@@ -80,7 +80,7 @@ class Dialog extends Component {
if (actions != null) if (actions != null)
dialogBody.add(new Container( dialogBody.add(new Container(
child: new Flex(actions, child: new Row(actions,
justifyContent: FlexJustifyContent.end justifyContent: FlexJustifyContent.end
) )
)); ));
......
...@@ -30,7 +30,7 @@ class DrawerHeader extends Component { ...@@ -30,7 +30,7 @@ class DrawerHeader extends Component {
), ),
padding: const EdgeDims.only(bottom: 7.0), padding: const EdgeDims.only(bottom: 7.0),
margin: const EdgeDims.only(bottom: 8.0), margin: const EdgeDims.only(bottom: 8.0),
child: new Flex([ child: new Column([
new Flexible(child: new Container()), new Flexible(child: new Container()),
new Container( new Container(
padding: const EdgeDims.symmetric(horizontal: 16.0), padding: const EdgeDims.symmetric(horizontal: 16.0),
...@@ -38,8 +38,7 @@ class DrawerHeader extends Component { ...@@ -38,8 +38,7 @@ class DrawerHeader extends Component {
style: Theme.of(this).text.body2, style: Theme.of(this).text.body2,
child: child child: child
) )
)], )]
direction: FlexDirection.vertical
) )
); );
} }
......
...@@ -91,7 +91,7 @@ class DrawerItem extends ButtonBase { ...@@ -91,7 +91,7 @@ class DrawerItem extends ButtonBase {
height: 48.0, height: 48.0,
decoration: new BoxDecoration(backgroundColor: _getBackgroundColor(themeData)), decoration: new BoxDecoration(backgroundColor: _getBackgroundColor(themeData)),
child: new InkWell( child: new InkWell(
child: new Flex(flexChildren) child: new Row(flexChildren)
) )
) )
); );
......
...@@ -94,7 +94,7 @@ class SnackBar extends Component { ...@@ -94,7 +94,7 @@ class SnackBar extends Component {
margin: const EdgeDims.symmetric(horizontal: 24.0), margin: const EdgeDims.symmetric(horizontal: 24.0),
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: new TextStyle(color: Theme.of(this).accentColor), style: new TextStyle(color: Theme.of(this).accentColor),
child: new Flex(children) child: new Row(children)
) )
) )
) )
......
...@@ -346,7 +346,7 @@ class Tab extends Component { ...@@ -346,7 +346,7 @@ class Tab extends Component {
} else if (label.text == null) { } else if (label.text == null) {
labelContent = _buildLabelIcon(); labelContent = _buildLabelIcon();
} else { } else {
labelContent = new Flex( labelContent = new Column(
<Widget>[ <Widget>[
new Container( new Container(
child: _buildLabelIcon(), child: _buildLabelIcon(),
...@@ -355,8 +355,7 @@ class Tab extends Component { ...@@ -355,8 +355,7 @@ class Tab extends Component {
_buildLabelText() _buildLabelText()
], ],
justifyContent: FlexJustifyContent.center, justifyContent: FlexJustifyContent.center,
alignItems: FlexAlignItems.center, alignItems: FlexAlignItems.center
direction: FlexDirection.vertical
); );
} }
...@@ -609,8 +608,6 @@ class TabNavigator extends Component { ...@@ -609,8 +608,6 @@ class TabNavigator extends Component {
); );
Widget content = views[selectedIndex].buildContent(); Widget content = views[selectedIndex].buildContent();
return new Flex([tabBar, new Flexible(child: content)], return new Column([tabBar, new Flexible(child: content)]);
direction: FlexDirection.vertical
);
} }
} }
...@@ -68,13 +68,12 @@ class ToolBar extends Component { ...@@ -68,13 +68,12 @@ class ToolBar extends Component {
Widget content = new Container( Widget content = new Container(
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: sideStyle, style: sideStyle,
child: new Flex([ child: new Column([
new Container( new Container(
child: new Flex(children), child: new Row(children),
height: kToolBarHeight height: kToolBarHeight
), ),
], ],
direction: FlexDirection.vertical,
justifyContent: FlexJustifyContent.end justifyContent: FlexJustifyContent.end
) )
), ),
......
...@@ -26,31 +26,40 @@ order to make them easier to use. ...@@ -26,31 +26,40 @@ order to make them easier to use.
Layout models Layout models
------------- -------------
- `Flex` Layout a list of child widgets in either the horizontal or vertical There are two _flex_ layout models:
`direction`. The direction along which the widgets are laid out is called the
*main* direction and the other axis is called the *cross* direction. A `Flex`
widget sizes itself to the maximum size permitted by its parent.
Each child of a `Flex` widget is either *flexible* or *inflexible*. The flex - `Row`: Layout a list of child widgets in the horizontal direction.
first lays out its inflexible children and subtracts their total length along
the main direction to determine how much free space is available. The flex
then divides this free space among the flexible children in a ratio
determined by their `flex` properties.
The `alignItems` property determines how children are positioned in the cross - `Column': Layout a list of child widgets in the vertical direction.
direction. The `justifyContent` property determines how the remaining free
space (if any) in the main direction is allocated.
- `Flexible` Mark this child as being flexible with the given `flex` ratio. The direction along which the widgets are laid out is called the
*main* direction and the other axis is called the *cross* direction.
These flex widgets size themselves to the maximum size permitted by
its parent, unless that would be infinite size, in which case they
shrink-wrap their children. For details, see [flex.md](flex.md).
- `Stack` Layout a list of child widgets on top of each other from back to Each child of a flex widget is either *flexible* or *inflexible*.
The flex first lays out its inflexible children and subtracts their
total length along the main direction to determine how much free space
is available. The flex then divides this free space among the flexible
children in a ratio determined by their `flex` properties.
The `alignItems` property determines how children are positioned in
the cross direction. The `justifyContent` property determines how the
remaining free space (if any) in the main direction is allocated.
- `Flexible`: Mark this child as being flexible with the given `flex` ratio.
There is also a stacking layout model:
- `Stack`: Layout a list of child widgets on top of each other from back to
front. Each child of a `Stack` widget is either *positioned* or front. Each child of a `Stack` widget is either *positioned* or
*non-positioned*. The stack sizes itself to the contain all the *non-positioned*. The stack sizes itself to the contain all the
non-positioned children, which are located at the top-left corner of the non-positioned children, which are located at the top-left corner of the
stack. The *positioned* children are then located relative to the stack stack. The *positioned* children are then located relative to the stack
according to their `top`, `right`, `bottom`, and `left` properties. according to their `top`, `right`, `bottom`, and `left` properties.
- `Positioned` Mark this child as *positioned*. If the `top` property is - `Positioned`: Mark this child as *positioned*. If the `top` property is
non-null, the top edge of this child will be positioned `top` layout units non-null, the top edge of this child will be positioned `top` layout units
from the top of the stack widget. The `right`, `bottom`, and `right` from the top of the stack widget. The `right`, `bottom`, and `right`
properties work analogously. Note that if the both the `top` and `bottom` properties work analogously. Note that if the both the `top` and `bottom`
......
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