Flutter學習筆記(23)--多個子元素的布局Widget(Rwo、Column、Stack、IndexedStack、Table、Wrap)


如需轉載,請注明出處:Flutter學習筆記(23)--多個子元素的布局Widget(Rwo、Column、Stack、IndexedStack、Table、Wrap)

 

上一篇梳理了擁有單個子元素布局的Widget,今天來梳理一下擁有多個子元素布局的Widget。

  • Row

Row組件常見屬性如下:

mainAxisAlignment:主軸的排列方式

crossAxisAlignment:次軸的排列方式

mainAxisSize:主軸應該占據多少空間,取值max為最大,min為最小

children:組件子元素,它的本質是一個List列表

對於Row來說,水平方向是主軸,垂直方向是次軸。

首先來看一下mainAxisAlignment屬性值都有哪些

enum MainAxisAlignment {
  start,//將子控件放在主軸開始的位置
  end,//將子控件放在主軸結束的位置
  center,//將子控件放在主軸中間的位置
  spaceBetween,//將主軸空白位置進行均分,排列子元素,首尾沒有空隙
  spaceAround,//將主軸空白區域均分,使中間各個子控件間距相等,首尾子控件間距為中間子控件間距的一半
  spaceEvenly,//將主軸空白區域均分,使各個子空間間距相等
}

Demo示例:

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            new Text('11111111111'),
            new Text('22222222222'),
            new Text('33333333333')
          ],
        ),
      ),
    );
  }
}

  • Column

Column組件常見屬性如下:

mainAxisAlignment:主軸的排列方式

crossAxisAlignment:次軸的排列方式

mainAxisSize:主軸應該占據多少空間,取值max為最大,min為最小

children:組件子元素,它的本質是一個List列表

對Column來說,垂直方向是主軸,水平方向是次軸,使用上和Row大同小異

Demo示例:

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            new Text('11111111111'),
            new Text('22222222222'),
            new Text('33333333333')
          ],
        ),
      ),
    );
  }
}

  • Stack

Stack/alignment:

Stack組件的每一個子組件要么定位,要么不定位,定位的子組件是用Positioned組件包裹的,Stack組件本身包含所有不定位的子組件,子組件根據alignment屬性定位(默認為左上角)。然后根據定位的子組件的top、right、bottom、left屬性將他們放置在Stack組件上。

Stack既然是允許子元素堆疊的組件,那么定位堆疊位置的屬性值有哪些呢?

alignment屬性值:bottomCenter 底部中間位置、bottomLeft 底部左側位置、bottomRight 底部右側位置、center 正中間位置、centerLeft 中間居左位置、centerRight 中間居右位置、topCenter 上部居中位置、topLeft 上部居左位置、topRight 上部居右位置

Demo示例:

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Center(
          child: new Stack(
            alignment: Alignment.centerLeft,
            children: <Widget>[
              new Container(
                width: 200.0,
                height: 200.0,
                color: Colors.blue,
              ),
              new Text('這是一段文本')
            ],
          ),
        ),
      ),
    );
  }
}

Stack/Positioned:

上面的示例是通過系統提供的定位來給子元素進行堆疊,但是實際工作中,上面的幾類屬性值往往不能滿足我們UI的需求,UI可能會要求子元素放在任何你想不到的位置,那么這時候就需要用到我們Positioned來進行定位了。

Positioned屬性值:top 子元素相對頂部邊界距離,left 子元素相對左側邊界距離,right 子元素相對右側邊界距離,bottom 子元素相對底部邊界距離。

Demo示例:

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Center(
          child: new Stack(
            children: <Widget>[
              new Container(
                width: 200.0,
                height: 200.0,
                color: Colors.blue,
              ),
              new Positioned(
                top: 20.0,
                left: 50.0,
                child: new Text('這是一段文本')
              )
            ],
          ),
        ),
      ),
    );
  }
}

  • IndexedStack

IndexedStack繼承自Stack,它的作用是顯示第index個child,其他的child都是不可見的,所以IndexedStack的尺寸永遠是和最大的子節點尺寸一致。由於IndexedStack是繼承自Stack,所以它只比Stack多了一個index屬性,即對應child的索引。

Demo示例:

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Center(
          child: new IndexedStack(
            index: 1,
            children: <Widget>[
              new Container(
                width: 200.0,
                height: 200.0,
                color: Colors.blue,
              ),
              new Positioned(
                top: 20.0,
                left: 50.0,
                child: new Text('這是一段文本')
              )
            ],
          ),
        ),
      ),
    );
  }
}

  • Table

Table表格布局,每一行的高度由其內容決定,每一列的寬度由columnWidths屬性單獨控制。

Table組件常見屬性如下:

columnWidths:設置每一列的寬度。

defaultColumnWidth:默認的每一列寬度,默認情況下均分。

textDirection:文字方向。

border:表格邊框。

defaultVerticalAlignment:默認垂直方向的對齊方式,top 放置在頂部、middle 垂直居中、bottom 放置在底部、baseline 文本baseline對齊、fill 充滿整個cell

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Table(
          defaultVerticalAlignment: TableCellVerticalAlignment.bottom,
          // 設置表格有多少列,並且指定列寬
          columnWidths:const <int,TableColumnWidth> {
            0:FixedColumnWidth(40.0),
            1:FixedColumnWidth(40.0),
            2:FixedColumnWidth(60.0),
            3:FixedColumnWidth(60.0),
            4:FixedColumnWidth(130.0),
          },
          // 設置表格邊框樣式
          border: TableBorder.all(
            color: Colors.blue,
            width: 2.0,
            style: BorderStyle.solid
          ),
          children: const <TableRow>[
            // 添加第一行數據
            TableRow(
              children: <Widget>[
                SizedBox(
                  child: Text('姓名'),
                  height: 30,
                ),
                Text('性別'),
                Text('年齡'),
                Text('身高'),
                Text('備注'),
              ],
            ),
            // 添加第二行數據
            TableRow(
              children: <Widget>[
                Text('張三'),
                Text(''),
                Text('20'),
                Text('186'),
                Text('學渣'),
              ],
            ),
            // 添加第三行數據
            TableRow(
              children: <Widget>[
                Text('李四'),
                Text(''),
                Text('20'),
                Text('188'),
                Text('學酥'),
              ],
            ),
            // 添加第四行數據
            TableRow(
              children: <Widget>[
                Text('王五'),
                Text(''),
                Text('21'),
                Text('177'),
                Text('學霸'),
              ],
            ),
            // 添加第五行數據
            TableRow(
              children: <Widget>[
                Text('小梅'),
                Text(''),
                Text('22'),
                Text('170'),
                Text('學神,需要重點培養'),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

  • Wrap

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Children Demo',
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Children Demo'),
        ),
        body: new Wrap(
          spacing: 3.0,
          runSpacing: 20.0,//縱軸方向的間距
          alignment: WrapAlignment.end,//縱軸方向的對其方式
          children: <Widget>[
            new Chip(
              avatar: CircleAvatar(
                backgroundColor: Colors.blue,
                child: new Text('A'),
              ),
              label: new Text('文本一'),
            ),
            new Chip(
              avatar: CircleAvatar(
                backgroundColor: Colors.blue,
                child: new Text('B'),
              ),
              label: new Text('文本二'),
            ),
            new Chip(
              avatar: CircleAvatar(
                backgroundColor: Colors.blue,
                child: new Text('C'),
              ),
              label: new Text('文本三'),
            ),
            new Chip(
              avatar: CircleAvatar(
                backgroundColor: Colors.blue,
                child: new Text('D'),
              ),
              label: new Text('文本四'),
            ),
            new Chip(
              avatar: CircleAvatar(
                backgroundColor: Colors.blue,
                child: new Text('E'),
              ),
              label: new Text('文本五'),
            ),
          ],
        ),
      ),
    );
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM