美文网首页
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