Flutter 常用布局widgets

2022-06-09 09:51 更新

Flutter擁有豐富的布局widget,但這里有一些最常用的布局widget。其目的是盡可能快地讓您構(gòu)建應(yīng)用并運行,而不是讓您淹沒在整個完整的widget列表中。 

以下widget分為兩類:widgets library中的標準widget和Material Components library中的專用widget 。 任何應(yīng)用程序都可以使用widgets library中的widget,但只有Material應(yīng)用程序可以使用Material Components庫。


標準 widgets

  • Container添加 padding, margins, borders, background color, 或?qū)⑵渌b飾添加到widget.
  • GridView將 widgets 排列為可滾動的網(wǎng)格.
  • ListView將widget排列為可滾動列表
  • Stack將widget重疊在另一個widget之上.


Material Components

  • Card將相關(guān)內(nèi)容放到帶圓角和投影的盒子中。
  • ListTile將最多3行文字,以及可選的行前和和行尾的圖標排成一行


Container

許多布局會自由使用容器來使用padding分隔widget,或者添加邊框(border)或邊距(margin)。您可以通過將整個布局放入容器并更改其背景顏色或圖片來更改設(shè)備的背景。


Container 概要 :

  • 添加padding, margins, borders
  • 改變背景顏色或圖片
  • 包含單個子widget,但該子widget可以是Row,Column,甚至是widget樹的根

a diagram showing that margins, borders, and padding, that surround content in a container

Container 示例:

除了下面的例子之外,本教程中的許多示例都使用了Container。 您還可以在Flutter Gallery中找到更多容器示例。

該布局中每個圖像使用一個Container來添加一個圓形的灰色邊框和邊距。然后使用容器將列背景顏色更改為淺灰色。

Dart code: main.dart, snippet belowImages: imagesPubspec: pubspec.yaml

a screenshot showing 2 rows, each containing 2 images; the images have grey rounded borders, and the background is a lighter grey

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

    var container = new Container(
      decoration: new BoxDecoration(
        color: Colors.black26,
      ),
      child: new Column(
        children: [
          new Row(
            children: [
              new Expanded(
                child: new Container(
                  decoration: new BoxDecoration(
                    border: new Border.all(width: 10.0, color: Colors.black38),
                    borderRadius:
                        const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  margin: const EdgeInsets.all(4.0),
                  child: new Image.asset('images/pic1.jpg'),
                ),
              ),
              new Expanded(
                child: new Container(
                  decoration: new BoxDecoration(
                    border: new Border.all(width: 10.0, color: Colors.black38),
                    borderRadius:
                        const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  margin: const EdgeInsets.all(4.0),
                  child: new Image.asset('images/pic2.jpg'),
                ),
              ),
            ],
          ),
        ],
      ),
    );
    //...
  }
}


GridView

使用GridView將widget放置為二維列表。 GridView提供了兩個預(yù)制list,或者您可以構(gòu)建自定義網(wǎng)格。當GridView檢測到其內(nèi)容太長而不適合渲染框時,它會自動滾動。

GridView 概覽:

  • 在網(wǎng)格中放置widget
  • 檢測列內(nèi)容超過渲染框時自動提供滾動
  • 構(gòu)建您自己的自定義grid,或使用一下提供的grid之一:GridView.count 允許您指定列數(shù)GridView.extent 允許您指定項的最大像素寬度

注意: 在顯示二維列表時,重要的是單元格占用哪一行和哪一列時, 應(yīng)該使用Table或 DataTable。

GridView 示例:

a 3-column grid of photos

使用GridView.extent 創(chuàng)建最大寬度為150像素的網(wǎng)格Dart code: main.dart, snippet belowImages: imagesPubspec: pubspec.yaml

a 2 column grid with footers containing titles on a partially translucent background

使用GridView.count 在縱向模式下創(chuàng)建兩個行的grid,并在橫向模式下創(chuàng)建3個行的網(wǎng)格。通過為每個GridTile設(shè)置footer屬性來創(chuàng)建標題。Dart code: grid_list_demo.dart from the Flutter Gallery

// The images are saved with names pic1.jpg, pic2.jpg...pic30.jpg.
// The List.generate constructor allows an easy way to create
// a list when objects have a predictable naming pattern.

List<Container> _buildGridTileList(int count) {

  return new List<Container>.generate(
      count,
      (int index) =>
          new Container(child: new Image.asset('images/pic${index+1}.jpg')));
}

Widget buildGrid() {
  return new GridView.extent(
      maxCrossAxisExtent: 150.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: 4.0,
      crossAxisSpacing: 4.0,
      children: _buildGridTileList(30));
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: buildGrid(),
      ),
    );
  }
}


ListView

ListView是一個類似列的widget,它的內(nèi)容對于其渲染框太長時會自動提供滾動。

ListView 摘要:

  • 用于組織盒子中列表的特殊Column
  • 可以水平或垂直放置
  • 檢測它的內(nèi)容超過顯示框時提供滾動
  • 比Column配置少,但更易于使用并支持滾動

ListView 示例:

a ListView containing movie theaters and restaurants

使用ListView顯示多個ListTile的業(yè)務(wù)列表。分隔線將劇院與餐廳分開

Dart code: main.dart, snippet belowIcons: Icons classPubspec: pubspec.yaml

a ListView containing shades of blue from the Material Design color palette

使用ListView控件來顯示Material Design palette中的ColorsDart code: Flutter Gallery中的 colors_demo.dart

List<Widget> list = <Widget>[
  new ListTile(
    title: new Text('CineArts at the Empire',
        style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
    subtitle: new Text('85 W Portal Ave'),
    leading: new Icon(
      Icons.theaters,
      color: Colors.blue[500],
    ),
  ),
  new ListTile(
    title: new Text('The Castro Theater',
        style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
    subtitle: new Text('429 Castro St'),
    leading: new Icon(
      Icons.theaters,
      color: Colors.blue[500],
    ),
  ),
];

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      // ...
      body: new Center(
        child: new ListView(
          children: list,
        ),
      ),
    );
  }
}


Stack

使用Stack來組織需要重疊的widget。widget可以完全或部分重疊底部widget。

Stack summary:

  • 用于與另一個widget重疊的widget
  • 子列表中的第一個widget是base widget; 隨后的子widget被覆蓋在基礎(chǔ)widget的頂部
  • Stack的內(nèi)容不能滾動
  • 您可以選擇剪切超過渲染框的子項

Stack 示例:

a circular avatar containing the label 'Mia B' in the lower right portion of the circle

使用Stack疊加Container(在半透明的黑色背景上顯示其文本),放置在Circle Avatar的頂部。Stack使用alignment屬性和調(diào)整文本偏移。Dart code: main.dart, snippet belowImage: imagesPubspec: pubspec.yaml

an image with a grey gradient across the top; on top of the gradient is tools painted in white

使用Stack將gradient疊加到圖像的頂部。gradient確保工具欄的圖標與圖片不同。Dart code: contacts_demo.dart

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var stack = new Stack(
      alignment: const Alignment(0.6, 0.6),
      children: [
        new CircleAvatar(
          backgroundImage: new AssetImage('images/pic.jpg'),
          radius: 100.0,
        ),
        new Container(
          decoration: new BoxDecoration(
            color: Colors.black45,
          ),
          child: new Text(
            'Mia B',
            style: new TextStyle(
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
        ),
      ],
    );
    // ...
  }
}


Card

Material Components 庫中的Card包含相關(guān)內(nèi)容塊,可以由大多數(shù)類型的widget構(gòu)成,但通常與ListTile一起使用。Card有一個子項, 但它可以是支持多個子項的列,行,列表,網(wǎng)格或其他小部件。默認情況下,Card將其大小縮小為0像素。您可以使用SizedBox來限制Card的大小。

在Flutter中,Card具有圓角和陰影,這使它有一個3D效果。更改Card的elevation屬性允許您控制投影效果。 例如,將elevation設(shè)置為24.0,將會使Card從視覺上抬離表面并使陰影變得更加分散。 有關(guān)支持的elevation值的列表,請參見Material guidelines中的Elevation and Shadows。 如果指定不支持的值將會完全禁用投影 。

Card 摘要:

  • 實現(xiàn)了一個 Material Design card
  • 接受單個子項,但該子項可以是Row,Column或其他包含子級列表的widget
  • 顯示圓角和陰影
  • Card內(nèi)容不能滾動
  • Material Components 庫的一個widget

Card 示例:

a Card containing 3 ListTiles 包含3個ListTiles并通過用SizedBox包裝進行大小調(diào)整的Card。分隔線分隔第一個和第二個ListTiles。Dart code: main.dart, snippet belowIcons: Icons classPubspec: pubspec.yaml

a Card containing an image and text and buttons under the image

包含圖像和文字的CardDart code: cards_demo.dart from the Flutter Gallery

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var card = new SizedBox(
      height: 210.0,
      child: new Card(
        child: new Column(
          children: [
            new ListTile(
              title: new Text('1625 Main Street',
                  style: new TextStyle(fontWeight: FontWeight.w500)),
              subtitle: new Text('My City, CA 99984'),
              leading: new Icon(
                Icons.restaurant_menu,
                color: Colors.blue[500],
              ),
            ),
            new Divider(),
            new ListTile(
              title: new Text('(408) 555-1212',
                  style: new TextStyle(fontWeight: FontWeight.w500)),
              leading: new Icon(
                Icons.contact_phone,
                color: Colors.blue[500],
              ),
            ),
            new ListTile(
              title: new Text('costa@example.com'),
              leading: new Icon(
                Icons.contact_mail,
                color: Colors.blue[500],
              ),
            ),
          ],
        ),
      ),
    );
  //...
}


ListTile

ListTile是Material Components庫中的一個專門的行級widget,用于創(chuàng)建包含最多3行文本和可選的行前和行尾圖標的行。ListTile在Card或ListView中最常用,但也可以在別處使用。

ListTile 摘要:

  • 包含最多3行文本和可選圖標的專用行
  • 比起Row不易配置,但更易于使用
  • Material Components 庫里的widget

ListTile 示例:

a Card containing 3 ListTiles

包含3個ListTiles的CardDart code: See Card examples.

3 ListTiles, each containing a pull-down button

使用ListTile列出3個下拉按鈕類型。Dart code: buttons_demo.dart from the Flutter Gallery


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號