likes
comments
collection
share

Flutter中的布局(二)

作者站长头像
站长
· 阅读数 14

一、常见的布局小部件

Flutter拥有丰富的布局小部件库。这里有一些最常用的。目的是为了让您尽快启动并运行,而不是用完整的列表让您不知所措。有关其他可用小部件的信息,请参阅小部件目录,或使用API 参考文档中的搜索框。

以下小部件分为两类:小部件库中的标准小部件和Material库中的专用小部件。任何应用程序都可以使用小部件库名,但只有Material应用程序可以使用 Material Components库。

1.1、标准小部件

  • Container:向小部件添加填充、边距、边框、背景颜色或其他装饰。
  • GridView:将小部件布置为可滚动的网格。
  • ListView:将小部件布置为可滚动列表。
  • Stack:将一个小部件重叠在另一个小部件之上。

1.2、Material 小部件

  • Card:将相关信息组织到一个带有圆角和阴影的框中。
  • ListTile:将最多3行文本和可选的前导和尾随图标组织成一行。

1.3、Container

许多布局自由使用Container来使用填充分隔小部件,或者添加边框或边距。您可以通过将整个布局放入Container并更改其背景颜色或图像来更改设备的背景。

1.3.1、详情(Container)

  • 添加填充、边距、边框。
  • 更改背景颜色或图像。
  • 包含单子子部件,但该子部件可以是行、列,甚至是部件树的根。

Flutter中的布局(二)

1.3.2、Example(Container)

此布局由一列和两行组成,每行包含2张图像。Conttainer用于将列的背景颜色更改为浅灰色。

Widget _buildImageColumn() {
    return Container(
        decoration: const BoxDecorarion(
            color: Colors.black26,
        ),
        child: Column(
            children: [
                _buildImageRow(1),
                _buildImageRow(3),
            ],
        ),
    );
}

Flutter中的布局(二)

Container还用于为每个图像添加圆角边框和边距:

Widget. _buildDecoratedImage(int imageIndex) => Expanded(
    child: Container(
        decoration: BoxDecoration(
            border: Border.all(width: 10, color: Colors.black38),
            borderRadius: const BorderRadius.all(Radius.circular(8)),
        ),
        margin: const.EdgeInsets.add(4),
        child: Image.asset('images/pic$imageIndex.jpg'),
    ),
); 

Wiget _buildImaggeRow(int imageIndex) => Row(
    children: [
        _buildDecoratedImage(imageIndex),
        _buildDecoratedImage(imageIndex + 1),
    ],
);

1.4、GridView

用于GridView将小部件布置二维列表。GridView提供了俩昂哥预制列表 ,或者您可以构建自己的自定义网格。当GGridView监测到其内容太长无法容纳渲染时,它会自动滚动。

1.4.1、详情(GridView)

  • 在网格中放置小部件
  • 监测列内容何时超出渲染框架并自动提供滚动
  • 构建您自己的自定义网格,或使用提供的网格之一:
    • GridView.count允许您指定列数
    • GridView.extent允许您指定图块的最大像素宽度。

1.4.2、Example(GridView)

Flutter中的布局(二) 用于GridView.extend创建具有最大 150像素宽的图块的网格。

Flutter中的布局(二) 用于GridView.count创建纵向模式下2格宽、横向模式下3格宽的网格。标题是通过footer为每个设置属性 来创建的GridTile

Widget _buildGrid() => GridView.extent(
    maxCrossAxisEntent: 150,
    padding: const EdgeInsets.all(4),
    mainAxisSpacing: 4,
    crossAxisSpacing: 4,
    children: _buildGridTileList(30));
);
// 图像以名称pic0.jpg、pic1.jpg...pic29.jpg保存。
// List.generate()构造函数允许一种简单的方法来创建,当对象具有可预测的命名模式时的列表。
List<Container> _buildGridTileList(int count) => List.generate(count, (i) => Container(child: Image.asset('images/pic$i.jpg')));

1.5、ListView

ListView一个类似列的小部件,当其内容对于其渲染框架来说太长时,会自动提供滚动。

1.5.1、详情(ListView)

  • 专门Column用于组织框列表的
  • 可以水平或垂直放置
  • 监测其内容何时不适合并提供滚动
  • 可配置性低于Column,但更易于使用并支持滚动。

1.5.2、Example(ListView)

Flutter中的布局(二) 使用ListView显示使用ListTiles的企业列表。分割线将剧院与餐厅隔开。

Flutter中的布局(二) 使用ListView显示来自Material Desiggn调色板的特定颜色系列的颜色。

Widget _buildList() {
    return ListView(
        children: [
            _tile('CineArts at the Empire', '85 W portal Ave', Icons.theaters),
            _tile('The Castro Theater', '429 Castro St', Icons.theaters),
            _tile('Alamo Drafthouse Cinema', '2550 Mission St', Icons.theaters),
            _tile('Roxie Theater', '3117 16th St', Icons.theaters),
            _tile('United Artists Stonestown Twin', '501 Buckingham Way',
          Icons.theaters),
            _tile('AMC Metreon 16', '135 4th St #3000', Icons.theaters),
      const Divider(),
            _tile('K's Kitchen', '757 Monterey Blvd', Icons.restaurant),
            _tile('Emmy's Restaurant', '1923 Ocean Ave', Icons.restaurant),
            _tile(
          'Chaiya Thai Restaurant', '272 Claremont Blvd', Icons.restaurant),
            _tile('La Ciccia', '291 30th St', Icons.restaurant),
        ],
    );
}

ListTile _tiile(String title, String. subtitle,  IconData icon) {
    return ListTile(
        title: Text(
            title,
            style: const TextStyle(
                fontWeight: FontWeight.w500,
                fontSize: 20,
            ),
        subtitle: Text(subtitle),
        leading: Icon(
            icon,
            color: Colors.blue[500],
        ),
        ),
    );
}

1.6、Stack

使用Stack将小部件排列在基本的小部件(通常是图像)之上。小部件可以完全或部分重叠基本小部件。

1.6.1、详情(Stack)

  • 用于与另一个小部件重叠的小部件。
  • 孩子列表中的第一个小部件是基本小部件;随后的子项覆盖在该基本小部件之上。
  • Stack的内容无法滚动。
  • 您可以选择剪辑超出渲染的子项。

1.6.2、Example(Stack)

Flutter中的布局(二) 使用Stack将容器(在半透明黑色背景上显示其文本)覆盖在CircleAvatar之上。Stack使用对齐属性和Alignments偏移文本。

Flutter中的布局(二) 使用Stack将图标叠加在图像之上。

Widget _buildStack() {
    return Stack(
        alignment: const Alignment(0.6, 0.6),
        children: [
            const CircleAvatar(
                backgroundImage: AssetImage('images/pic.jpg'),
                radius: 100,
            ),
            Container(
                decoration: const BoxDecoration(
                    color: Colors.black45,
                ),
                child: const Text(
                    foontSize: 20,
                    fontWeight: FongWeight.bold,
                    color: Colorss.white,
                ),
            ),
        ],
    );
}

1.7、Card

来自Material库的Card包含相关的信息块,几乎可以由任何小部件组成个,但通常与ListTile一起使用。Card有一个子项,但它的子项可以是列、行、列表、网格或其他支持多个子项的小部件。默认情况下,Card将其大小缩小为0 x 0像素。您可以使用SizedBox来限制卡片的大小。

在Flutter中,Card具有略微圆角和阴影,使其具有3D效果。更改Cardelevation属性允许您控制投影效果。例如,将高度设置为24,可以在视觉上将卡片从表面上抬的更远,并导致阴影变得更加分散。

1.7.1、详情(Card)

  • 实现Material Card
  • 用于呈现相关的信息块
  • 接受单个子项,但该子项可以是行、列或其他包含子项列表的小部件。
  • 以圆角和阴影显示
  • 卡片内容无法滚动
  • 来自Material库

1.7.2、Example(Card)

Flutter中的布局(二) 包含3个ListTiles并通过用SizedBox包裹来调整大小的CardDivider将第一个和第二个ListTiles分开。

Flutter中的布局(二) 包含图像和文本的卡片。

Widget _buildCard() {
    return SizedBox(
        height: 210,
        child: Card(
            child: Column(
                children: [
                    ListTile(
                        title: const Text(
                            '1625 Main Street',
                            style: TextStyle(fontWeight: FontWeight.w500),
                            subtitle: const Text('My City, CA 99984'),
                            leading: Icon(
                                icons.reasautant_menu,
                                color: Colors.blue[500].
                            ),
                        ),
                        const Divider(),
                        ListTile(
                            title: const. Text(
                                '(408)555-1212',
                                style: TextStyle(fontWeight: FontWeigght.w500),
                            ),
                            leading: Icon(
                                Icons.contact_phone,
                                color: Colors.blue[500],
                            ),
                        ),
                        ListTile(
                            title: const Text('costa@example.com'),
                            leading: Icon(
                                Icons.contact_mail,
                                color:  Colors.blue[500],
                            ),
                        ),
                    ),
                ],
            ),
        ),
    );
}

1.8、ListTile

使用ListTile,一种来自Material库的专用行小部件,可以轻松创建包含最多3行文本和可选的前导和尾随图标的行。ListTile最常用于CardListView,但也可以在其他地方使用。

1.8.1、详情(ListTile)

  • 包含最多3行文本和可选图标的专用行
  • 不如Row可配,但更易于使用
  • 来自Material库

1.8.2、Example(ListTile)

Flutter中的布局(二) 一个Card包含3个ListTile

Flutter中的布局(二) 使用带leading小部件的ListTile

二 、Constraints

要完全理解Flutter的系统布局,您需要了解Flutter如何在布局中定位组件并调整其大小。有关详细信息,请参阅了解Constraints

三、其他资源

以下资源可能有助于编写布局代码。