美文网首页
Flutter入门07 -- Widget之单个子元素的布局类

Flutter入门07 -- Widget之单个子元素的布局类

作者: YanZi_33 | 来源:发表于2022-02-21 13:47 被阅读0次
    • 涉及单个子元素布局类的Widget有:Container、Padding、Center、Align、FittedBox、AspectRatio、ConstrainedBox、Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth、LimitedBox、Offstage、OverflowBox、SizedBox、SizedOverflowBox、Transform、CustomSingleChildLayout,Positioned

    Container(容器布局)

    • Container是一个拥有绘制、定位、调整大小的widget,其构造方法如下:
    Container({
        Key key,
        this.alignment,
        this.padding,
        this.color,
        this.decoration,
        this.foregroundDecoration,
        double width,
        double height,
        BoxConstraints constraints,
        this.margin,
        this.transform,
        this.child,
        this.clipBehavior = Clip.none,
    })
    
    image.png
    • child:设置内部子组件;
    • margin:设置外边距,container与临近组件之间的距离,属于EdgeInsets类型;
    • padding:设置内边距,container内部子控件距离container的内部边距,属于EdgeInsets类型;
    • alignment:内部子控件在container中的排列方式,属于Alignment类型;
    • color:container的背景颜色,属于Colors类型;
    • decoration:container的背景装饰,与color是互斥的不能同时存在,decoration包含padding,不包含margin,可设置 边框、圆角、阴影、形状、渐变、背景图像,属于BoxDecoration类型;
      • border:设置边框,属于BoxBorder类型;
      • gradient:设置渐变色,属于Gradient类型;
      • boxShadow:设置阴影,属于List<BoxShadow>类型;
    • widthheightconstraints:容器的大小可以通过width、height属性来指定,也可以通过constraints来指定,如果它们同时存在时,width、height优先。实际上Container内部会根据width、height来生成一个constraints;
    • transform:设置container的变换矩阵,类型为Matrix4;
    class SFHomeBody extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          child: Text("520",style: TextStyle(color: Colors.white,fontSize: 38.0)), //设置子控件
          alignment: Alignment.centerLeft,  //设置内部布局
          constraints: BoxConstraints.tightFor(width: 200.0,height: 200.0), //设置尺寸
          margin: EdgeInsets.only(top: 120.0,left: 120.0), //设置外间距
          padding: EdgeInsets.all(10.0), //设置内边距
          decoration: BoxDecoration( //设置背景装饰
            gradient: RadialGradient( //设置背景渐变色
              colors: [Colors.red,Colors.orange],
              center: Alignment.topLeft,
              radius: .98
            ),
            boxShadow: [ //设置背景阴影
              BoxShadow(
                color: Colors.black54,
                offset: Offset(2.0,2.0),
                blurRadius: 4.0
              )
            ],
            border: Border.all(//设置边框
              width: 40.0,
              color: Colors.purple
            )
          ),
        );
      }
    }
    
    • 效果图如下所示:
    Snip20220214_13.png
    Container的注意点
    • Container在没有设置宽高和child子组件时,其尺寸大小 默认占据屏幕的剩余所有空间;
    • Container在只设置宽或者高时,其没有设置的高或者宽默认占据屏幕的剩余所有空间;
    • Container在没有设置宽高时,但设置了子组件child,其尺寸大小与子组件等大;
    • Container在没有设置宽高时,但设置了子组件child,且设置了alignment属性,其尺寸大小 默认占据屏幕的剩余所有空间;
    Center(居中布局)
    • 将子widget,居中显示在自身内部的widget,其构造函数如下:
    Center({ 
       Key key, 
       double widthFactor, 
       double heightFactor, 
       Widget child 
    })
    
    • widthFactor:宽度因子;
    • heightFactor:高度因子;
    • child:内部子组件;
    • 当widthFactor与heightFactor均为空时,Center的宽度尽可能最大,占据整个屏幕的宽度,Center的高度与内部child的高度相等;
    • 当widthFactor = 2,heightFactor为空时,Center的宽度等于child的宽度 * 2,Center的高度与内部child的高度相等;
    • 当heightFactor = 2,widthFactor为空时,Center的高度等于child的高度 * 2,Center的宽度尽可能最大,占据整个屏幕的宽度;
    • 当widthFactor = 2,heightFactor = 2时,Center的宽度等于child的宽度 * 2,Center的高度等于child的高度 * 2;
    • 案例代码如下:
    import 'package:flutter/material.dart';
    
    main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: SFHomePage(),
        );
      }
    }
    
    class SFHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          appBar: AppBar(
            title: Text("Flutter布局"),
          ),
          body: SFHomeBody(),
        );
      }
    }
    
    class SFHomeBody extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Column(
          children: [
            Container(
              color: Colors.red,
              child: Center(
                child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
              ),
            ),
            Container(
              margin: EdgeInsets.only(top: 10.0),
              color: Colors.red,
              child: Center(
                child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
                widthFactor: 2,
              ),
            ),
            Container(
              margin: EdgeInsets.only(top: 10.0),
              color: Colors.red,
              child: Center(
                child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
                heightFactor: 2,
              ),
            ),
            Container(
              margin: EdgeInsets.only(top: 10.0),
              color: Colors.red,
              child: Center(
                child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
                widthFactor: 2,
                heightFactor: 2,
              ),
            )
          ],
        );
      }
    }
    
    • 效果图如下:
    image.png

    Padding(填充布局)

    • 一个widget,可以给其子节点添加填充(留白),实现内边距效果,其构造函数如下:
    const Padding({
        Key key,
        @required this.padding,
        Widget child,
    })
    
    • padding:设置内边距,属于EdgeInsets类型,设置EdgeInsets的数值,通常有如下几种方式:
      • EdgeInsets.all(20):同时设置上下左右四个方向的内边距,且数值相同;
      • EdgeInsets.only(top: 10):可单独设置某个方向上的内边距;
      • EdgeInsets.fromLTRB(10, 10, 10, 10):同时设置四个方向上的内边距,数值不同;
      • EdgeInsets.symmetric(vertical: 15,horizontal: 25):设置垂直,水平方向上的内边距;
    • child:设置子组件;
    class SFHomeBody extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Column(
          children: [
            Container(
              color: Colors.red,
              margin: EdgeInsets.only(top: 10),
              child: Padding(
                child: Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
                padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
              ),
            ),
            Container(
              color: Colors.red,
              margin: EdgeInsets.only(top: 10),
              child: Padding(
                child:  Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
                padding: EdgeInsets.all(10)
              )
            ),
            Container(
              color: Colors.purple,
              margin: EdgeInsets.only(top: 10),
              child: Padding(
                child:  Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
                padding: EdgeInsets.only(left: 10,top: 15),
              ),
            ),
            Container(
              color: Colors.orange,
              margin: EdgeInsets.only(top: 10),
              child: Padding(
                child:  Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
                padding: EdgeInsets.symmetric(vertical: 15,horizontal: 25),
              ),
            )
          ],
        );
      }
    }
    
    • 效果图如下:
    image.png
    • Padding可作为单个组件,也可作为属性,设置内边距;

    Align(对齐布局)

    • 一个widget,它可以将其子widget对齐,并可以根据子widget的大小自动调整大小,构造函数如下:
    const Align({
        Key key,
        this.alignment = Alignment.center,
        this.widthFactor,
        this.heightFactor,
        Widget child,
    }) 
    
    • alignment:内部子组件的排列方式,属于Alignment类型;
    • child:内部子组件;
    • widthFactor:宽度因子;
    • heightFactor:高度因子;
    • 当widthFactor与heightFactor均为空时,Align的宽度尽可能最大,占据整个屏幕的宽度,Align的高度与内部child的高度相等;
    • 当widthFactor = 2,heightFactor为空时,Align的宽度等于child的宽度 * 2,Align的高度与内部child的高度相等;
    • 当heightFactor = 2,widthFactor为空时,Align的高度等于child的高度 * 2,Align的宽度尽可能最大,占据整个屏幕的宽度;
    • 当widthFactor = 2,heightFactor = 2时,Align的宽度等于child的宽度 * 2,Align的高度等于child的高度 * 2;
    • widthFactor和heightFactor的原理与Center的完全一致;
    class SFHomeBody extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Column(
          children: [
            Container(
              color: Colors.red,
              margin: EdgeInsets.only(top: 10),
              child: Align(
                alignment: Alignment.center,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.purple,
                ),
              )
            ),
            Container(
              color: Colors.red,
              margin: EdgeInsets.only(top: 10),
              child: Align(
                alignment: Alignment.center,
                widthFactor: 2,
                child: Container(
                  color: Colors.purple,
                  width: 50,
                  height: 50,
                ),
              )
            ),
            Container(
              color: Colors.red,
              margin: EdgeInsets.only(top: 10),
              child: Align(
                alignment: Alignment.center,
                heightFactor: 2,
                child: Container(
                  color: Colors.purple,
                  width: 50,
                  height: 50,
                ),
              )
            ),
            Container(
              color: Colors.red,
              margin: EdgeInsets.only(top: 10),
              child: Align(
                alignment: Alignment.center,
                widthFactor: 2,
                heightFactor: 2,
                child: Container(
                  color: Colors.purple,
                  width: 50,
                  height: 50,
                ),
              )
            )
          ],
        );
      }
    }
    
    • 效果图如下:
    image.png

    SizedBox

    • SizedBox:可用来设置两个widget之间的间距,也可用来限制子组件的大小;
    • 其构造函数如下:
    const SizedBox({ 
      Key key, 
      this.width, 
      this.height, 
      Widget child 
    })
    
    • 案例代码:
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class SFMinePage extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.white,
          alignment: Alignment.center,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              MaterialButton(
                onPressed: (){},
                onLongPress: (){},
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                child: Text(
                  "按钮"
                ),
                color: Colors.blue,
              ),
              SizedBox(
                child: Container(
                  color: Colors.green,
                ),
                height: 20,
                width: 100,
              ),
              TextField(
                onChanged: (String text){},
                decoration: InputDecoration(
                  filled: true,
                  fillColor: Colors.orange
                ),
              )
            ]
          ),
        );
      }
    }
    
    • 效果图如下:
    image.png

    OverflowBox

    • OverflowBox:允许子组件,溢出父组件显示,其构造函数如下:
    const OverflowBox({
        Key key,
        this.alignment = Alignment.center,
        this.minWidth,
        this.maxWidth,
        this.minHeight,
        this.maxHeight,
        Widget child,
    })
    
    • alignment:在父组件中的对齐方式;
    • child:设置子组件;
    • minWidth:最小宽度,如果子控件宽度小于这个值,子控件按这个值显示;
    • maxWidth:最大宽度,如果子控件宽度大于这个值,子控件按这个值显示;
    • minHeight:最小高度,如果子控件高度小于这个值,子控件按这个值显示;
    • maxHeight:最大高度,如果子控件高度大于这个值,子控件按这个值显示;
    • 案例代码如下:
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class SFMinePage extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.orange,
          width: 200,
          height: 200,
          padding: EdgeInsets.all(10),
          child: OverflowBox(
            alignment: Alignment.topLeft,
            maxHeight: 300,
            maxWidth: 300,
            child: Container(
              color: Colors.blue,
              width: 350,
              height: 350,
            ),
          ),
        );
      }
    }
    
    • 效果图如下:
    image.png
    • 蓝色超出父组件 溢出显示;
    • maxWidth最大宽度为300,虽然蓝色子组件设置了350,最终宽度按300显示;

    SizeOverflowBox

    • OverflowBox自身是没有尺寸的,但是SizedOverflowBox是有的,其构造函数如下:
    const SizedOverflowBox({
        Key key,
        @required this.size,
        this.alignment = Alignment.center,
        Widget child,
    })
    
    • size:设置宽高;
    • child:设置子组件;
    • alignment:在父组件中的对齐方式;
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class SFMinePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
              color: Colors.blue,
              child: SizedOverflowBox(
                alignment: Alignment.topCenter,
                size: Size(100, 50),
                child: Container(
                  width: 50,
                  height: 80,
                  color: Colors.amber,
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(top: 50),
              color: Colors.blue,
              height: 50,
              constraints: BoxConstraints(
                maxHeight: 50,
              ),
              child: OverflowBox(
                alignment: Alignment.topCenter,
                minWidth: 20,
                maxWidth: 100,
                maxHeight: 100,
                minHeight: 20,
                child: Container(
                  width: 50,
                  height: 120,
                  color: Colors.amber,
                ),
              ),
            )
          ],
        );
      }
    }
    
    • 效果图如下:
    image.png

    Positioned

    • Positioned:在Stack中,针对目标控件实现 定位,构造函数如下:
    const Positioned({
        Key key,
        this.left,
        this.top,
        this.right,
        this.bottom,
        this.width,
        this.height,
        @required Widget child,
    })
    
    • left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离;
    • width和height用于指定定位元素的宽度和高度;
    class SFHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        print("SFHomePage build");
        return Scaffold(
            appBar: AppBar(
              title: Text("商品列表"),
            ),
            body: ui3()
        );
      }
      
      Widget ui3() {
        return Stack(
          children: [
            Container(
              color: Colors.pink,
            ),
    
            Positioned(
              bottom: 30,
              left: 10,
              right: 10,
              child: Container(
                color: Colors.green,
                height: 100,
              ),
            )
          ],
        );
      }
    }
    
    • 效果图如下:
    image.png

    相关文章

      网友评论

          本文标题:Flutter入门07 -- Widget之单个子元素的布局类

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