美文网首页
Flutter -- 5.布局相关

Flutter -- 5.布局相关

作者: MissStitch丶 | 来源:发表于2021-11-04 10:01 被阅读0次
    • Flutter中,布局方式为弹性盒子布局
    • 可以将一个一个Widget看做一个一个矩形盒子,盒子套盒子模式

    1.Container

    • 如果没有设置child,Container大小与上层一致
    • 如果设置了child,大小与child大小一致
    • alignment(x,y),值范围从-1.0到1.0。设置子部件对齐方式。如果当前Container上层大小确定,设置alignment后,Container大小不受child大小影响
      • alignment(-1,-1),左上角。等于Alignment.topLeft
      • alignment(0,0),中间。等于Alignment.center
      • alignment(1,1),右下角。等于Alignment.bottomRight
    class ContainerDemo extends StatelessWidget {
      const ContainerDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
    
        return Container(
          color: Colors.grey[400],
          child: Container(
            width: 200,
            height: 200,
            color: Colors.red,
          ),
          alignment: Alignment.center, //设置后,不受child影响
        );
      }
    }
    
    layout_container.png layout_container_alignment.png

    2.Flex

    • Row、Column的父类
    • 可以沿着水平或垂直方向排列子Widget
    • direction,必填参数,排列方向
    class FlexDemo extends StatelessWidget {
      const FlexDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.grey[400],
          child: Flex(
            direction: Axis.horizontal,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 80,
                color: Colors.blue,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(aspectRatio: 1,),
              ),
            ],
          ),
        );
      }
    }
    
    laout_flex_horizontal laout_flex_vertical

    3.主轴

    • 类型为MainAxisAlignment
    • 横向布局,默认方向为由左向右
    • 纵向布局,默认方向为由上到下
    • start - 主轴最开始地方,默认值
    • center - 主轴中间地方
    • end - 主轴结束地方
    • spaceBottom - 小组件间的间距的平均分布
    • spaceAround - 小组件间周围平均分布
    • spaceEvenly - 小组件均匀分布
    class FlexDemo extends StatelessWidget {
      const FlexDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.grey[400],
          alignment: Alignment.center,
          child: Flex(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            direction: Axis.horizontal,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 80,
                color: Colors.blue,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(aspectRatio: 1,),
              ),
            ],
          ),
        );
      }
    }
    
    flex_mainAxisAlignment_start.png flex_mainAxisAlignment_center.png flex_mainAxisAlignment_end.png
    flex_mainAxisAlignment_spaceBetween.png flex_mainAxisAlignment_spaceAround.png flex_mainAxisAlignments_paceEvenly.png

    4.交叉轴

    • 类型为MainAxisAlignment
    • start - 交叉轴最开始地方
    • center - 交叉轴中间地方,默认值
    • end - 交叉轴结束地方
    • stretch - 交叉轴方向拉伸满
    • spaceAround - 小组件间周围平均分布
    • baseLIne - 基准线。当direction: Axis.horizontal时,多个小部件为Text时,基于文字对齐。英文alphabetic其他语言ideographic注意这里只有设置了textBaseLine才能设置,否则会报错
    class FlexBaselineDemo extends StatelessWidget {
      const FlexBaselineDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.grey[400],
          alignment: Alignment.center,
          child: Flex(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            crossAxisAlignment: CrossAxisAlignment.baseline,
            /*
            * TextBaseLine
            * alphabetic,英文
            * ideographic,其他语言
            * 测试完感觉2者在中文/英文来用任意一个都差不多
            * */
            textBaseline: TextBaseline.ideographic, 
            direction: Axis.horizontal,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(
                  aspectRatio: 1,
                  child: Center(
                    child: Text("红色", style: TextStyle(fontSize: 15, color: Colors.white),),
                  ),
                ),
              ),
              Container(
                width: 80,
                color: Colors.blue,
                child: const AspectRatio(
                  aspectRatio: 1,
                  child: Center(
                    child: Text("蓝色", style: TextStyle(fontSize: 20, color: Colors.white),),
                  ),
                ),
              ),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(
                  aspectRatio: 1,
                  child: Center(
                    child: Text("黄色", style: TextStyle(fontSize: 30, color: Colors.white),),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
    
    flex_crossAxisAlignment_start.png flex_crossAxisAlignment_center.png flex_crossAxisAlignment_end.png
    flex_crossAxisAlignment_stretch.png flex_crossAxisAlignment_baseline_ideographic.png flex_crossAxisAlignment_baseline_alphabetic.png

    5.Row、Column

    • Row、Column继承Flex
    • Row相当于Flex中direction: Axis.horizontal
    • Column相当于Flex中direction: Axis.vertical
    • 使用方式与Flex一致
    • 注意:textDirection设置后可以改变主轴方向,仅在Row上改变主轴方向
    class RowOrColumnDemo extends StatelessWidget {
    
      final bool isRow;
      
      const RowOrColumnDemo(this.isRow);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.grey[400],
          alignment: Alignment.center,
          child: isRow ? Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 80,
                color: Colors.blue,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(aspectRatio: 1,),
              ),
            ],
          ) :
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 80,
                color: Colors.blue,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(aspectRatio: 1,),
              ),
            ],
          ) ,
        );
      }
    }
    

    6.Stack

    • 视图叠着排列,z方向
    • 方向,由里到外
    • 一般设置alignment来设置子部件显示的位置
    • 需要设置宽高或依赖子部件宽高撑大
    • Positioned,在Stack下也可以使用Positioned来设置小部件位置
    class StackDemo extends StatelessWidget {
    
      final bool isShowPositioned;
    
      const StackDemo(this.isShowPositioned);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.grey[400],
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height - kToolbarHeight - _statusBarHeight,
          child: Stack(
            alignment: Alignment.center,
            children: [
              Container(
                width: 200,
                height: 200,
                color: Colors.red,
              ),
              Container(
                width: 150,
                height: 150,
                color: Colors.blue,
              ),
              Container(
                width: 100,
                height: 100,
                color: Colors.yellow,
              ),
              if (isShowPositioned) Positioned(
                right: 0,
                width: 50,
                height: 150,
                top: 150,
                child: Container(
                  color: Colors.purple,
                )),
            ],
          ),
        );
      }
    }
    
    stack_normal.png stack_positioned.png

    7. AspectRatio

    • 设置当前部件的宽高比。注意只会影响当前部件,不会影响子部件
    • 当父部件宽高都已经设置后,设置的宽高比失效
    Container(
      width: 200,
      height: 150,
      color: Colors.red,
      child: const AspectRatio(aspectRatio: 1,), //失效
    )
    

    8.Expanded

    • 在主轴上不会剩余间隙,将会被Expanded拉伸。设置后,主轴小部件之间间距将变为0
    • flex为弹性系数,系数越大拉伸的距离占比越大。主轴方向下的所有Expanded按照其flex的比例来分割全部的空闲空间
    • 这里使用Row来演示
    class ExpandedDemo extends StatelessWidget {
    
      final bool isRow;
    
      const ExpandedDemo({required this.isRow});
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.grey[400],
          alignment: Alignment.center,
          child: isRow ? Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Expanded( //蓝色在主轴上填满
                child: Container(
                  color: Colors.blue,
                  child: const AspectRatio(aspectRatio: 1,),
                ),),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(aspectRatio: 1,),
              ),
            ],
          ) :
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 60,
                color: Colors.red,
                child: const AspectRatio(aspectRatio: 1,),
              ),
              Expanded( //蓝色在主轴上填满
                child: Container(
                  width: 80,
                  color: Colors.blue,
                  child: const AspectRatio(aspectRatio: 1,),
                ),
              ),
              Container(
                width: 100,
                color: Colors.yellow,
                child: const AspectRatio(aspectRatio: 1,),
              ),
            ],
          ) ,
        );
      }
    }
    
    row_expanded.png column_expanded.png

    9.margin&padding

    • margin,外边距。影响当前部件的内容边距
    • padding,内边距。影响当前子部件的内容边距

    相关文章

      网友评论

          本文标题:Flutter -- 5.布局相关

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