美文网首页
Flutter笔记(四) - Flutter的布局Widget(

Flutter笔记(四) - Flutter的布局Widget(

作者: 南城同學 | 来源:发表于2021-11-01 09:46 被阅读0次

    多子布局组件

    在开发中,我们经常需要将多个Widget放在一起进行布局,比如水平方向、垂直方向排列,甚至有时候需要他们进行层叠,比如图片上面放一段文字等;
    这个时候我们需要使用多子布局组件(Multi-child layout widgets)。
    比较常用的多子布局组件是Row、Column、Stack。

    1. Flex组件

    Row组件和Column组件都继承自Flex;

    • Flex组件和RowColumn属性主要的区别就是多一个 direction;
    • direction的值为Axis.horizontal的时候,则是Row,呈一行排布;
    • direction的值为Axis.vertical的时候,则是Column,呈一列排布;

    它们都有主轴(Main Axis)和交叉轴(Cross Axis)的概念:

    • 对于Row来说,水平方向是主轴,竖直方向是交叉轴;


      Row@2x.png
    • 对于Column来说,竖直方向是主轴,水平方向是交叉轴;


      Column.png

    2. Row组件

    Row({
      Key key,
      MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主轴对齐方式
      MainAxisSize mainAxisSize = MainAxisSize.max, // 水平方向尽可能大
      CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 交叉处对齐方式
      TextDirection textDirection, // 水平方向子widget的布局顺序(默认为系统当前Locale环境的文本方向(如中文、英语都是从左往右,而阿拉伯语是从右往左))
      VerticalDirection verticalDirection = VerticalDirection.down, // 表示Row纵轴(垂直)的对齐方向
      TextBaseline textBaseline, // 如果上面是baseline对齐方式,那么选择什么模式(有两种可选)
      List<Widget> children = const <Widget>[],
    })
    

    2.1. mainAxisSize

    Row的特点:

    • 水平方向尽可能占据较大的空间;

    • 垂直方向包裹内容;


      WechatIMG49.jpeg
    • 如果水平方向也希望包裹内容,那么设置mainAxisSize = min;


      WechatIMG48.jpeg
    return RaisedButton(
            onPressed: (){
            },
          color: Colors.red,
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.favorite),
              Text("收藏"),
            ],
          ),
        );
    

    2.2. mainAxisAlignment

    元素在Row主轴上的布局方式,它是一个枚举类型:

    • start :主轴开始的位置挨个摆放元素;
    • end :主轴结束的位置挨个摆放元素;
    • center :主轴的中心点对齐;
    • spaceBetween: 左右两边的间距为0,其他元素之间平分间距;
    • spaceAround:左右两边的间距是其他元素的间距的一半;
    • spaceEvenly:间距平分;
    class _YZHomeContentState extends State<YZHomeContent> {
      @override
      Widget build(BuildContext context) {
        return Row(
          children: [
            Container(width: 80, height: 60, color: Colors.red,),
            Container(width: 120, height: 100, color: Colors.orange,),
            Container(width: 90, height: 80, color: Colors.blue,),
            Container(width: 50, height: 50, color: Colors.green,),
          ],
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        );
      }
    }
    
    WechatIMG50.jpeg

    2.3. CrossAxisAlignment

     crossAxisAlignment: CrossAxisAlignment.end,
    

    元素在Row交叉轴上的布局方式

    • start:交叉轴的起始位置对齐;
    • end:交叉轴的结束位置对齐(垂直方向是包裹内容的);
    • center:中心点对齐(默认值)
    • baseLine:基线对齐;(必须有文本才有效果)
    • stretch: 先将Row占据交叉轴尽可能大的空间,再将所有的子Widget拉伸到最大;

    2.4. Expanded

    空间分配:拉伸或收缩;

    • 如果控件之间有间隔:拉伸;
    • 如果控件组合宽度超过了屏幕,则压缩;


      WechatIMG943.jpeg

      如上图,间隔等分,如果想把所有间隔分配给第一个;

    return  Row(
          children: [
            Expanded(
                child: Container(width: 80, height: 60, color: Colors.red,),
            ),
            Container(width: 120, height: 100, color: Colors.orange,),
            Container(width: 90, height: 80, color: Colors.blue,),
            Container(width: 50, height: 50, color: Colors.green,),
          ],
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.end,
        );
      }
    }
    

    效果:

    • 第一个控件宽度做了拉伸;


      WechatIMG942.jpeg
    2.4.1 flex作用
     Expanded(
           flex: 1,
           child: Container(width: 80, height: 60, color: Colors.red,),
     ),
    Expanded(
            flex: 2,
            child: Container(width: 40, height: 60, color: Colors.green,),
      ),
    

    剩余空间分配比例: 当有多个Expanded时,

    • 如果flex相等,则拉伸的宽度相同;
    • 如果flex不等,按比例拉伸,如上面flex:2控件的宽度拉伸为flex: 1宽度的2倍,原来的width数值不再起作用。

    3. Column组件

    同Row;


    4. Stack组件

    在开发中,我们多个组件很有可能需要重叠显示,比如在一张图片上显示文字或者一个按钮等。在Flutter中我们需要使用层叠布局Stack。

    4.1 Stack介绍

    Stack的大小默认是包裹内容的.

    • alignment:从什么位置开始排布所有的子Widget;
    • fit: expand 将子元素拉伸到尽可能大;
    • overflow:超出部分如何处理;
      Stack({
        Key key,
        this.alignment = AlignmentDirectional.topStart,
        this.textDirection,
        this.fit = StackFit.loose,
        this.overflow = Overflow.clip,
        this.clipBehavior = Clip.hardEdge,
        List<Widget> children = const <Widget>[],
      }) 
    

    4.2 示例

    class _YZHomeContentState extends State<YZHomeContent> {
      @override
      Widget build(BuildContext context) {
        return Stack(
          alignment: AlignmentDirectional.bottomCenter,
          overflow: Overflow.visible,
          children: [
            Image.asset("assets/images/image_01.png",),
            Container(width: 150, height: 50, color: Colors.red,),
            // Positioned( //文字在Stack内部相对布局调整
            //   right: 10,
            //   bottom: 20,
            //   child:
              Text("这是图片上的文字"),
            // ),
          ],
        );
      }
    }
    
    
    WechatIMG51.jpeg
    class _YZHomeContentState extends State<YZHomeContent> {
    
       bool _isFavor = false;
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: [
            Image.asset("assets/images/image_02.jpeg",width: MediaQuery.of(context).size.width,),
            Positioned(
              left: 0,
              right: 0,
              bottom: 0,
              child: Container(
                padding: EdgeInsets.all(8),
                color: Color.fromARGB(10, 0, 0, 0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text("这是图片上的文字描述", style: TextStyle(fontSize: 15, color: Colors.red),),
                    IconButton(
                        icon: Icon(
                            Icons.favorite,
                            color: _isFavor ? Colors.red : Colors.white,
                        ),
                        onPressed: () {
                          setState(() {
                            _isFavor = !_isFavor;
                          });
                    }),
                  ],
                ),
              ),
            ),
          ],
        );
      }
    }
    
    WechatIMG52.jpeg

    相关文章

      网友评论

          本文标题:Flutter笔记(四) - Flutter的布局Widget(

          本文链接:https://www.haomeiwen.com/subject/tvrzqltx.html