1 Transform

平移 Transform.translate

  1. DecoratedBox(
  2. decoration:BoxDecoration(color: Colors.red),
  3. //默认原点为左上角,左移20像素,向上平移5像素
  4. child: Transform.translate(
  5. offset: Offset(-20.0, -5.0),
  6. child: Text("Hello world"),
  7. ),
  8. )

旋转 Transform.rotate

  1. import 'dart:math' as math;
  2. DecoratedBox(
  3. decoration:BoxDecoration(color: Colors.red),
  4. child: Transform.rotate(
  5. //旋转90度
  6. angle:math.pi/2 ,
  7. child: Text("Hello world"),
  8. ),
  9. );

缩放Transform.scale

  1. DecoratedBox(
  2. decoration:BoxDecoration(color: Colors.red),
  3. child: Transform.scale(
  4. scale: 1.5, //放大到1.5倍
  5. child: Text("Hello world")
  6. )
  7. );

image.png

  1. Container(
  2. color: Colors.black,
  3. child: new Transform(
  4. alignment: Alignment.topRight, //相对于坐标系原点的对齐方式
  5. transform: new Matrix4.skewY(0.3), //沿Y轴倾斜0.3弧度
  6. child: new Container(
  7. padding: const EdgeInsets.all(8.0),
  8. color: Colors.deepOrange,
  9. child: const Text('Apartment for rent!'),
  10. ),
  11. ),
  12. );

image.png

2 RotatedBox

RotatedBox和Transform.rotate功能相似,都可以对子组件进行旋转变换,
有一点不同:RotatedBox的变换是在layout阶段,会影响在子组件的位置和大小

  1. Row(
  2. mainAxisAlignment: MainAxisAlignment.center,
  3. children: <Widget>[
  4. DecoratedBox(
  5. decoration: BoxDecoration(color: Colors.red),
  6. //将Transform.rotate换成RotatedBox
  7. child: RotatedBox(
  8. quarterTurns: 1, //旋转90度(1/4圈)
  9. child: Text("Hello world"),
  10. ),
  11. ),
  12. Text("你好", style: TextStyle(color: Colors.green, fontSize: 18.0),)
  13. ],
  14. ),

image.png

3 装饰容器DecoratedBox & BoxDecoration


DecoratedBox可以在其子组件绘制前(或后)绘制一些装饰(Decoration),如背景、边框、渐变

  1. const DecoratedBox({
  2. Decoration decoration,
  3. DecorationPosition position = DecorationPosition.background,
  4. Widget child
  5. });
  6. /*
  7. decoration:代表将要绘制的装饰,它的类型为Decoration。Decoration是一个抽象类,它定义了一个接口 createBoxPainter(),子类的主要职责是需要通过实现它来创建一个画笔,该画笔用于绘制装饰。
  8. position:此属性决定在哪里绘制Decoration,它接收DecorationPosition的枚举类型,该枚举类有两个值:
  9. background:在子组件之后绘制,即背景装饰。
  10. foreground:在子组件之上绘制,即前景。
  11. */

我们通常会直接使用BoxDecoration类,它是一个Decoration的子类,实现了常用的装饰元素的绘制。

  1. BoxDecoration({
  2. Color color, //颜色
  3. DecorationImage image,//图片
  4. BoxBorder border, //边框
  5. BorderRadiusGeometry borderRadius, //圆角
  6. List boxShadow, //阴影,可以指定多个
  7. Gradient gradient, //渐变
  8. BlendMode backgroundBlendMode, //背景混合模式
  9. BoxShape shape = BoxShape.rectangle, //形状
  10. })

案例:

  1. DecoratedBox(
  2. decoration: BoxDecoration(
  3. gradient: LinearGradient(colors:[Colors.red,Colors.orange[700]]), //背景渐变
  4. borderRadius: BorderRadius.circular(3.0), //3像素圆角
  5. boxShadow: [ //阴影
  6. BoxShadow(
  7. color:Colors.black54,
  8. offset: Offset(2.0,2.0),
  9. blurRadius: 4.0
  10. )
  11. ]
  12. ),
  13. child: Padding(padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),
  14. child: Text("Login", style: TextStyle(color: Colors.white),),
  15. )
  16. )

4 FittedBox (缩放布局,不会超过父容器)

fit:缩放方式,默认属性是 BoxFit.contain

  1. BoxFit
  2. BoxFit.none //没有任何填充模式
  3. BoxFit.fill //不按宽高比例填充,内容不会超过容器范围
  4. BoxFit.contain //按照宽高比等比模式填充,内容不会超过容器范围
  5. BoxFit.cover //按照原始尺寸填充整个容器模式。内容可能回超过容器范围
  6. BoxFit.width //按照宽高比等比模式填充,适配宽度
  7. BoxFit.height //按照宽高比等比模式填充,适配高度
  8. BoxFit.scaleDown //会根据情况缩小范围

alignment: 设置对齐方式,默认属性是 Aligment.center,居中显示 child

  1. class MyApp extends StatelessWidget {
  2. // This widget is the root of your application.
  3. @override
  4. Widget build(BuildContext context) {
  5. return MaterialApp(
  6. title: '布局示例',
  7. home: LayoutDemo(),
  8. );
  9. }
  10. }
  11. class LayoutDemo extends StatelessWidget {
  12. @override
  13. Widget build(BuildContext context) {
  14. return new Scaffold(
  15. appBar: AppBar(
  16. title: Text('Center'),
  17. ),
  18. body: Container(
  19. width: 250,
  20. height: 250,
  21. color: Colors.grey,
  22. child: FittedBox(
  23. fit: BoxFit.scaleDown,
  24. alignment: Alignment.topLeft,
  25. child: Container(
  26. color: Colors.deepOrange,
  27. child: Text('缩放布局'),
  28. ),
  29. ),
  30. ),
  31. );
  32. }
  33. }

5 FractionallySizedBox根据父容器宽高的百分比来设置子组件宽高

widthFactor 宽度缩放因子

heightFactor 高度缩放因子

  1. FractionallySizedBox(
  2. // 对齐方式
  3. alignment: Alignment.center,
  4. // 宽度因子 1为占满整行
  5. widthFactor: 1,
  6. // 高度因子
  7. heightFactor: 1,
  8. child: Text("123"),
  9. );

6 ConstrainedBox(带限制的盒子)

constraints:BoxConstraints

BoxConstraints属性

  1. const BoxConstraints({
  2. this.minWidth = 0.0, //最小宽度
  3. this.maxWidth = double.infinity, //最大宽度
  4. this.minHeight = 0.0, //最小高度
  5. this.maxHeight = double.infinity //最大高度
  6. })

ConstrainedBox使用

  1. ConstrainedBox(
  2. constraints: BoxConstraints(
  3. minWidth: double.infinity, //宽度尽可能大
  4. minHeight: 50.0 //最小高度为50像素
  5. ),
  6. child: Container(
  7. height: 5.0,
  8. child: redBox
  9. ),
  10. )
  11. /*
  12. 虽然将Container的高度设置为5像素,但是最终却是50像素,
  13. 这是ConstrainedBox的最小高度限制生效了。
  14. 如果将Container的高度设置为80像素,那么最终红色区域的高度也会是80像素
  15. */

7 LimitedBox (限制最大宽高布局)

  1. /*
  2. const LimitedBox({
  3. Key key,
  4. this.maxWidth = double.infinity,
  5. this.maxHeight = double.infinity,
  6. Widget child,
  7. })
  8. */
  9. LimitedBox(
  10. maxWidth: 150.0,//设置最大宽度 限定child在此范围内
  11. child: Container(
  12. color: Colors.lightGreen,
  13. width: 250.0,
  14. ),
  15. )

8 Baseline

  1. //baseline的构造函数
  2. const Baseline({
  3. Key key,
  4. @required this.baseline,
  5. @required this.baselineType,
  6. Widget child,
  7. })
  • baseline基准线位置,是以像素为基本的单位
  • baselineType 定位child的基准线类型,分为两种:alphabetic对齐字符底部的水平线,ideographic对齐表意字符的水平线
    1. Row(
    2. mainAxisAlignment: MainAxisAlignment.spaceBetween,
    3. children: <Widget>[
    4. new Baseline(
    5. baseline: 80.0,
    6. baselineType: TextBaseline.alphabetic,
    7. child: new Text(
    8. 'AaBbCc',
    9. style: new TextStyle(
    10. fontSize: 18.0,
    11. textBaseline: TextBaseline.alphabetic,
    12. ),
    13. ),
    14. ),
    15. new Baseline(
    16. baseline: 80.0,
    17. baselineType: TextBaseline.alphabetic,
    18. child: new Container(
    19. width: 40.0,
    20. height: 40.0,
    21. color: Colors.green,
    22. ),
    23. ),
    24. new Baseline(
    25. baseline: 80.0,
    26. baselineType: TextBaseline.alphabetic,
    27. child: new Text(
    28. 'DdEeFf',
    29. style: new TextStyle(
    30. fontSize: 26.0,
    31. textBaseline: TextBaseline.alphabetic,
    32. ),
    33. ),
    34. )
    35. ],
    36. )
    [

](https://blog.csdn.net/huang3513/article/details/97639004)

9 TabBar

通过AppBar的“bottom”属性来添加一个导航栏底部Tab按钮组
image.png

TabBar + TabController + TabBarView

  1. class _ScaffoldRouteState extends State<ScaffoldRoute>
  2. with SingleTickerProviderStateMixin {
  3. TabController _tabController; //需要定义一个Controller
  4. List tabs = ["新闻", "历史", "图片"];
  5. @override
  6. void initState() {
  7. super.initState();
  8. // 创建Controller
  9. _tabController = TabController(length: tabs.length, vsync: this);
  10. }
  11. @override
  12. Widget build(BuildContext context) {
  13. return Scaffold(
  14. appBar: AppBar(
  15. ... //省略无关代码
  16. bottom: TabBar(
  17. controller: _tabController,
  18. tabs: tabs.map((e) => Tab(text: e)).toList()),
  19. ),
  20. drawer: new MyDrawer(),
  21. body: TabBarView(
  22. controller: _tabController,
  23. children: tabs.map((e) { //创建3个Tab页
  24. return Container(
  25. alignment: Alignment.center,
  26. child: Text(e, textScaleFactor: 5),
  27. );
  28. }).toList(),
  29. ),
  30. ... // 省略无关代码
  31. );
  32. }

10 Flex 弹性布局

direction:扩展方向

flex:弹性系数

flex为弹性系数,如果为0或null,则child是没有弹性的,即不会被扩伸占用的空间。如果大于0,所有的Expanded按照其flex的比例来分割主轴的全部空闲空间

  1. Flex(
  2. direction: Axis.horizontal,
  3. children: <Widget>[
  4. Expanded(
  5. flex: 1,
  6. child: Container(
  7. height: 80.0,
  8. color: Colors.red,
  9. ),
  10. ),
  11. Expanded(
  12. flex: 2,
  13. child: Container(
  14. height: 80.0,
  15. color: Colors.green,
  16. ),
  17. ),
  18. ],
  19. ),

11 Wrap:解决row/column被撑破的问题

[

](https://book.flutterchina.club/chapter4/wrap_and_flow.html)

  1. //火爆专区子项
  2. Widget _wrapList(){
  3. if(hotGoodsList.length!=0){
  4. List<Widget> listWidget = hotGoodsList.map((val){
  5. return InkWell(
  6. onTap:(){print('点击了火爆商品');},
  7. child:
  8. Container(
  9. width: ScreenUtil().setWidth(372),
  10. color:Colors.white,
  11. padding: EdgeInsets.all(5.0),
  12. margin:EdgeInsets.only(bottom:3.0),
  13. child: Column(
  14. children: <Widget>[
  15. Image.network(val['image'],width: ScreenUtil().setWidth(375),),
  16. Text(
  17. val['name'],
  18. maxLines: 1,
  19. overflow:TextOverflow.ellipsis ,
  20. style: TextStyle(color:Colors.pink,fontSize: ScreenUtil().setSp(26)),
  21. ),
  22. Row(
  23. children: <Widget>[
  24. Text('¥${val['mallPrice']}'),
  25. Text(
  26. '¥${val['price']}',
  27. style: TextStyle(color:Colors.black26,decoration: TextDecoration.lineThrough),
  28. )
  29. ],
  30. )
  31. ],
  32. ),
  33. )
  34. );
  35. }).toList();
  36. return Wrap(
  37. spacing: 8.0, // 主轴(水平)方向间距
  38. runSpacing: 4.0, // 纵轴(垂直)方向间距
  39. alignment: WrapAlignment.center, //纵轴方向的对齐方式:沿主轴方向居中
  40. children: listWidget,
  41. );
  42. }else{
  43. return Text(' ');
  44. }
  45. }

12 Flow:性能好,且灵活,一般少用,需要自己实现FlowDelegate

  1. //对六个色块进行自定义流式布局:
  2. Flow(
  3. delegate: TestFlowDelegate(margin: EdgeInsets.all(10.0)),
  4. children: <Widget>[
  5. new Container(width: 80.0, height:80.0, color: Colors.red,),
  6. new Container(width: 80.0, height:80.0, color: Colors.green,),
  7. new Container(width: 80.0, height:80.0, color: Colors.blue,),
  8. new Container(width: 80.0, height:80.0, color: Colors.yellow,),
  9. new Container(width: 80.0, height:80.0, color: Colors.brown,),
  10. new Container(width: 80.0, height:80.0, color: Colors.purple,),
  11. ],
  12. )
  13. //实现TestFlowDelegate:
  14. class TestFlowDelegate extends FlowDelegate {
  15. EdgeInsets margin = EdgeInsets.zero;
  16. TestFlowDelegate({this.margin});
  17. @override
  18. void paintChildren(FlowPaintingContext context) {
  19. var x = margin.left;
  20. var y = margin.top;
  21. //计算每一个子widget的位置
  22. for (int i = 0; i < context.childCount; i++) {
  23. var w = context.getChildSize(i).width + x + margin.right;
  24. if (w < context.size.width) {
  25. context.paintChild(i,
  26. transform: new Matrix4.translationValues(
  27. x, y, 0.0));
  28. x = w + margin.left;
  29. } else {
  30. x = margin.left;
  31. y += context.getChildSize(i).height + margin.top + margin.bottom;
  32. //绘制子widget(有优化)
  33. context.paintChild(i,
  34. transform: new Matrix4.translationValues(
  35. x, y, 0.0));
  36. x += context.getChildSize(i).width + margin.left + margin.right;
  37. }
  38. }
  39. }
  40. @override
  41. getSize(BoxConstraints constraints){
  42. //指定Flow的大小
  43. return Size(double.infinity,200.0);
  44. }
  45. @override
  46. bool shouldRepaint(FlowDelegate oldDelegate) {
  47. return oldDelegate != this;
  48. }
  49. }

13 PageView

PageView

  1. class PageViewDemo extends StatelessWidget {
  2. @override
  3. Widget build(BuildContext context) {
  4. // TODO: implement build
  5. return PageView(
  6. // pageSnapping: false, //这个值默认是true;此值为true时当拖动划过一半会切换到下一个页面,否则会弹回上一个页面;此值为false时,滑动多少就切换多少
  7. // reverse: true,//页面顺序倒置
  8. // scrollDirection: Axis.vertical,//页面滚动方向
  9. onPageChanged: (currentPage) =>
  10. debugPrint('page:$currentPage'), //页面切换的回调,
  11. controller: PageController(
  12. initialPage: 1,
  13. keepPage: false, //是否记住滚动到的页面
  14. viewportFraction: 1.0, //页面占可视窗口的比例
  15. ),
  16. children: <Widget>[
  17. Container(
  18. color: Colors.brown[900],
  19. alignment: Alignment(0.0, 0.0),
  20. child: Text(
  21. 'ONE',
  22. style: TextStyle(fontSize: 32.0, color: Colors.white),
  23. ),
  24. ),
  25. Container(
  26. color: Colors.green[900],
  27. alignment: Alignment(0.0, 0.0),
  28. child: Text(
  29. 'TWO',
  30. style: TextStyle(fontSize: 32.0, color: Colors.white),
  31. ),
  32. ),
  33. Container(
  34. color: Colors.red[900],
  35. alignment: Alignment(0.0, 0.0),
  36. child: Text(
  37. 'THREE',
  38. style: TextStyle(fontSize: 32.0, color: Colors.white),
  39. ),
  40. )
  41. ],
  42. );
  43. }
  44. }

PageView.builder

  1. class ViewDemo extends StatelessWidget {
  2. Widget _pageItemBuilder(BuildContext context, int index) {
  3. return Stack(
  4. children: <Widget>[
  5. SizedBox.expand(
  6. child: Image.network(
  7. posts[index].imageUrl,
  8. fit:BoxFit.cover
  9. ),
  10. ),
  11. Positioned(
  12. bottom: 8.0,
  13. left: 8.0,
  14. child: Column(
  15. crossAxisAlignment: CrossAxisAlignment.start,
  16. children: <Widget>[
  17. Text(
  18. posts[index].title,
  19. style:TextStyle(fontWeight: FontWeight.bold)
  20. ),
  21. Text(
  22. posts[index].author,
  23. ),
  24. ],
  25. ),
  26. ),
  27. ],
  28. );
  29. }
  30. @override
  31. Widget build(BuildContext context) {
  32. // TODO: implement build
  33. return PageView.builder(
  34. itemCount: posts.length,
  35. itemBuilder: _pageItemBuilder,
  36. );
  37. }
  38. }

14 Stack & Positioned

Stack

  1. Stack({
  2. this.alignment = AlignmentDirectional.topStart,
  3. this.textDirection,
  4. this.fit = StackFit.loose,
  5. this.overflow = Overflow.clip,
  6. List children = const [],
  7. })
  • alignment:此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子组件。所谓部分定位,在这里特指没有在某一个轴上定位:left、right为横轴,top、bottom为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位。
  • textDirection:和Row、Wrap的textDirection功能一样,都用于确定alignment对齐的参考系,即:textDirection的值为TextDirection.ltr,则alignment的start代表左,end代表右,即从左往右的顺序;textDirection的值为TextDirection.rtl,则alignment的start代表右,end代表左,即从右往左的顺序。
  • fit:此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose表示使用子组件的大小,StackFit.expand表示扩伸到Stack的大小。
  • overflow:此属性决定如何显示超出Stack显示空间的子组件;值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible 时则不会。

Positioned

  1. const Positioned({
  2. Key key,
  3. this.left,
  4. this.top,
  5. this.right,
  6. this.bottom,
  7. this.width,
  8. this.height,
  9. @required Widget child,
  10. })


left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。width和height用于指定需要定位元素的宽度和高度。注意,Positioned的width、height 和其它地方的意义稍微有点区别,此处用于配合left、top 、right、 bottom来定位组件,举个例子,在水平方向时,你只能指定left、right、width三个属性中的两个,如指定left和width后,right会自动算出(left+width),如果同时指定三个属性则会报错,垂直方向同理。

示例

  1. //通过ConstrainedBox来确保Stack占满屏幕
  2. ConstrainedBox(
  3. constraints: BoxConstraints.expand(),
  4. child: Stack(
  5. alignment:Alignment.center , //指定未定位或部分定位widget的对齐方式
  6. children: [
  7. Container(
  8. child: Text("Hello world",style: TextStyle(color: Colors.white)),
  9. color: Colors.red,
  10. ),
  11. Positioned(
  12. left: 18.0,
  13. child: Text("I am Jack"),
  14. ),
  15. Positioned(
  16. top: 18.0,
  17. child: Text("Your friend"),
  18. )
  19. ],
  20. ),
  21. );

15 Align (对齐布局)

Align组件可以调整子组件的位置,并且可以根据子组件的宽高来确定自身的的宽高,定义如下:

  1. Align({
  2. Key key,
  3. this.alignment = Alignment.center,
  4. this.widthFactor,
  5. this.heightFactor,
  6. Widget child,
  7. })
  • alignment: 需要一个AlignmentGeometry类型的值,表示子组件在父组件中的起始位置。AlignmentGeometry是一个抽象类,它有两个常用的子类:Alignment和FractionalOffset
  • widthFactor和heightFactor是用于确定Align组件本身宽高的属性;它们是两个缩放因子,会分别乘以子元素的宽、高,最终的结果就是Align组件的宽高。如果值为null,则组件的宽高将会占用尽可能多的空间。

[

](https://book.flutterchina.club/chapter4/alignment.html)

  1. /*
  2. static const Alignment topLeft = Alignment(-1.0, -1.0);
  3. static const Alignment topCenter = Alignment(0.0, -1.0);
  4. static const Alignment topRight = Alignment(1.0, -1.0);
  5. static const Alignment centerLeft = Alignment(-1.0, 0.0);
  6. static const Alignment center = Alignment(0.0, 0.0);
  7. static const Alignment centerRight = Alignment(1.0, 0.0);
  8. static const Alignment bottomLeft = Alignment(-1.0, 1.0);
  9. static const Alignment bottomCenter = Alignment(0.0, 1.0);
  10. static const Alignment bottomRight = Alignment(1.0, 1.0);
  11. */
  12. Container(
  13. height: 120.0,
  14. width: 120.0,
  15. color: Colors.blue[50],
  16. child: Align(
  17. alignment: Alignment.topRight,
  18. child: FlutterLogo(
  19. size: 60,
  20. ),
  21. ),
  22. )

16 Padding (设置边距填充布局)

给其子节点添加填充(留白)

  1. Padding(
  2. //上下左右各添加16像素补白
  3. padding: EdgeInsets.all(16.0),
  4. child: Column(
  5. //显式指定对齐方式为左对齐,排除对齐干扰
  6. crossAxisAlignment: CrossAxisAlignment.start,
  7. children: <Widget>[
  8. Padding(
  9. //左边添加8像素补白
  10. padding: const EdgeInsets.only(left: 8.0),
  11. child: Text("Hello world"),
  12. ),
  13. Padding(
  14. //上下各添加8像素补白
  15. padding: const EdgeInsets.symmetric(vertical: 8.0),
  16. child: Text("I am Jack"),
  17. ),
  18. Padding(
  19. // 分别指定四个方向的补白
  20. padding: const EdgeInsets.fromLTRB(20.0,.0,20.0,20.0),
  21. child: Text("Your friend"),
  22. )
  23. ],
  24. ),
  25. );

17 Opacity(透明度处理)

  1. /** 设置子控件透明度
  2. const Opacity({
  3. Key key,
  4. @required this.opacity,//透明度,0.0 到 1.0,0.0表示完全透明,1.0表示完全不透明
  5. this.alwaysIncludeSemantics = false,
  6. Widget child,
  7. })
  8. */
  9. Opacity(
  10. opacity:0.5,
  11. child:Text('透明度50%'),
  12. )

18 AspectRatio(宽高比)

  1. aspectRatio不能为null,必须是大于0的有限的值<br /> 如果父组件有指定宽高,则响应父组件的宽和高设置
  1. /**
  2. AspectRatio作用于父控件,根据aspectRatio计算父控件的宽或者高,AspectRatio的子控件将填充满父控件,子控件的宽高无效。
  3. 强制子部件的宽度和高度具有给定的宽高比,可以父容器给定一个宽或者高,来换算另一个值
  4. const AspectRatio({
  5. Key key,
  6. @required this.aspectRatio,//宽高比
  7. Widget child
  8. })
  9. */
  10. Container(
  11. width: 100.0,
  12. child: AspectRatio(
  13. aspectRatio: 2.0 / 3.0,
  14. child: Container(
  15. color: Color(0xffff0000),
  16. ),
  17. ),
  18. )

19 IndexedStack (显示第index个child,其他child都不可见)

  1. IndexedStack({ Key key,
  2. AlignmentGeometry alignment = AlignmentDirectional.topStart,
  3. TextDirection textDirection,
  4. StackFit sizing = StackFit.loose,
  5. this.index = 0,
  6. List<Widget> children = const <Widget>[],
  7. })
  • IndexedStack和Stack一样,都可以在一个组件上面放置另一个组件,唯一不同的是IndexedStack只能同时显示子组件中的一个组件,并通过Index属性来设置要显示的控件
  • alignment: 设置子组件在Stack中的对齐方式
  • index: 要显示的子组件的下标,对应children的List的下标
  • textDirection:设置子组件在Stack中从左往右排列,还是从右往左排列
  • sizing:调整IndexedStack组件中的没有使用Position包裹的子组件的宽高

loose: 子组件的宽高从Stack约束的最小值到最大值之间取值
expand: 子组件的宽高取Stack约束的最大值
passthrough:从父组件传递到Stack组件的约束将不加修改地传递给Stack组件中没有被Position组件包裹的子组件

  1. IndexedStack(
  2. alignment: AlignmentDirectional.center,
  3. textDirection: TextDirection.ltr,
  4. sizing: StackFit.loose,
  5. index: 0,
  6. children: [
  7. Container(
  8. width: 100,
  9. height: 100,
  10. color: Colors.red,
  11. ),
  12. Container(
  13. width: 80,
  14. height: 80,
  15. color: Colors.blue,
  16. ),
  17. Container(
  18. width: 50,
  19. height: 50,
  20. color: Colors.green,
  21. ),
  22. ],
  23. );

[

](https://blog.csdn.net/gzx110304/article/details/102541042)
[

](https://blog.csdn.net/gzx110304/article/details/102541042)

21 OverflowBox (溢出父容器显示)

当OverflowBox的最大尺寸大于child的时候,child可以完整显示
否则以最大尺寸为基准maxWidth maxHeight

  1. const OverflowBox({ Key key,
  2. this.alignment = Alignment.center,
  3. this.minWidth,
  4. this.maxWidth,
  5. this.minHeight,
  6. this.maxHeight,
  7. Widget child,
  8. })
  • OverflowBox允许其子组件溢出OverflowBox的父组件显示
  • minWidth:对子组件的最小宽度约束
  • maxWidth:对子组件的最大宽度约束
  • minHeight:对子组件的最小高度约
  • maxHeight:对子组件的最大高度约束

注意:设置maxWidth或者maxHeight时,其值不能小于父组件的宽高,如果父组件有padding限制,则其值不能小于父组件的宽高减去Padding

  1. Container(
  2. height: 100.0,
  3. width: 100.0,
  4. color: Colors.black26,
  5. child: OverflowBox(
  6. maxWidth: 80.0,
  7. minWidth: 50.0,
  8. minHeight: 50.0,
  9. maxHeight: 80.0,
  10. child: Container(
  11. width: 100.0,
  12. height: 200.0,
  13. color: Colors.blue,
  14. ),
  15. ),
  16. )

蓝色的Container的最大高度不会超过80,最小高度不会小于50.最大宽度不会超过80,最小高度不会小于50.