每天进步一点点策略大本营2:自由,平等,友爱。文集小岛

[Flutter开发]02.如何构建一个Flutter布局

2020-03-09  本文已影响0人  沈枫_ShenF

前言

在Flutter中,几乎所有东西都是一个widget,包括对齐(alignment)、填充(padding)和布局(layout)。widget的主要工作是提供一个build()方法来描述如何通过简单的widget来构建复杂的widget来显示自己,例如官方中下面的UI:

上面的UI可以通过一个行包含3列,其中每列包含一个图标和一个标签来完成。

在Flutter中,Widget的作用是描述UI元素的配置数据,它并不是表示最终绘制在设备屏幕上的显示元素,而它只是描述显示元素的一个配置数据。

而实际上显示元素的类是Element,也就是说Widget只是描述Element的配置数据!Widget只是UI元素的一个配置数据,并且一个Widget可以对应多个Element。这是因为同一个Widget对象可以被添加到UI树的不同部分,而真正渲染时,UI树的每一个Element节点都会对应一个Widget对象,所以:

Flutter拥有丰富的布局widget,但是把握一些最常用的布局widget就可以了,毕竟我们最终想尽可能快构建应用并运行起来,而不是让自己淹没在整个完整的widget列表中,其他需要用到的再去翻阅文档即可。

布局分类

布局widget大致可分为两类:
  1. Single-child layout widgets,它们都有一个child属性,只能包含一个子级widget。

例如: Container、Padding、Center等等。

  1. Multi-child layout widgets,它们都有一个 children属性,可以包含多个子级widget。

例如: Row,Column,ListView或Stack等等。

常用组件

Container

也是一个widget,只有它能设置填充,边距,边框或背景色。
概要 :

appBar: new AppBar(
  title: new Text(widget.title),
),
body: new Center(
  child: new Row(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      new Expanded(
        child: new Image.asset('images/pic1.jpg'),
      ),
      new Expanded(
        flex: 2,
        child: new Image.asset('images/pic2.jpg'),
      ),
      new Expanded(
      .....

最终结果:

GridView

网格组件,可滚动。自定义grid,或使用一下提供的grid之一:

ListView

相比Column,ListView是一种列状布局,如果其内容太长而无法适应可用空间,则会自动滚动,而且你可以设置滚动方向, 比如:

ListView还可以设置关屏时垃圾收集机制:addAutomaticKeepAlives: false。
并可以控制cache大小:cacheExtent:100.0,它是一个预加载概念,表示出现在可视区域上下各 cacheExtent 大小区域内的元素会被提前加载。
可以设置分割线:separatorBuilder:(,) => Divider()。
也可以通过mySliverChildDelegate构建自定义的ListView:

ListView.custom(
    childrenDelegate: mySliverChildDelegate
);

具体用法,推荐看这篇文章:Flutter 中 ListView 组件的子元素曝光统计

ListTile

相比Row,ListTile是一个易于使用的小部件,具有前后图标属性以及最多3行文本,并且能通过onTap和onLongPress回调,进行交互。

Stack

使用Stack来组织需要重叠的widget。widget可以完全或部分重叠底部widget,子列表中的第一个widget是base widget; 随后的子widget被覆盖在基础widget的顶部,Stack的内容不能滚动。Stack使用alignment属性和调整文本偏移。

Card

属于Single-child layout,可以使用SizedBox来限制Card的大小。
Card具有圆角和阴影,这使它有一个3D效果。可以通过更改Card的elevation属性来控制投影效果。Card内容不能滚动。

DefaultTextStyle.merge

DefaultTextStyle.merge可以允许您创建一个默认的文本样式,该样式会被其所有的子节点继承。

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // ...

    var descTextStyle = new TextStyle(
      color: Colors.black,
      fontWeight: FontWeight.w800,
      fontFamily: 'Roboto',
      letterSpacing: 0.5,
      fontSize: 18.0,
      height: 2.0,
    );

    var iconList = DefaultTextStyle.merge(
      style: descTextStyle,
      child: new Container(
        padding: new EdgeInsets.all(20.0),
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            new Column(
              children: [
                new Icon(Icons.kitchen, color: Colors.green[500]),
                new Text('PREP:'),
                new Text('25 min'),
              ],
            ),
            new Column(
              children: [
                new Icon(Icons.timer, color: Colors.green[500]),
                new Text('COOK:'),
                new Text('1 hr'),
              ],
            ),
            new Column(
              children: [
                new Icon(Icons.restaurant, color: Colors.green[500]),
                new Text('FEEDS:'),
                new Text('4-6'),
              ],
            ),
          ],
        ),
      ),
    );
    // ...
  }
}
上一篇 下一篇

猜你喜欢

热点阅读