Flutter 67: 图解基本约束 Box (二)

简介: 0 基础学习 Flutter,第六十七步:学习基础约束 Box (二)!

      小菜继续学习约束 Box 的各类应用;

UnconstrainedBox

源码分析

class UnconstrainedBox extends SingleChildRenderObjectWidget {
    const UnconstrainedBox({
        Key key,
        Widget child,
        this.textDirection,                 // 文字方向
        this.alignment = Alignment.center,  // 对齐方式
        this.constrainedAxis,               // 是否保留约束轴方向
    })
}

      分析源码可得,UnconstrainedBox 继承自 SingleChildRenderObjectWidget,与 ConstrainedBox 效果相反,给子 Widget 提供不加限制的空间;

案例尝试

      UnconstrainedBox 不会对子 Widget 进行约束限制,按照其子 Widget 大小进行绘制;小菜理解为去除父 Widget 的限制,让子 Widget 完全绘制;

1. alignment

      用于子 Widget 的对齐方向,可以通过 AlignmentAlignmentDirectional 进行调整所在位置;其中 AlignmentDirectional start/y 范围是 [-1.0, 1.0]

2. textDirection

      当 alignment 使用 AlignmentDirectional 方式设置对齐方式时,textDirection 用于从左到右或从右到左的起始方向;

return Container(height: 180, width: 180, color: Colors.blueAccent.withOpacity(0.4),
    child: UnconstrainedBox(constrainedAxis: null,
        alignment: AlignmentDirectional(-1.0, 1.0), textDirection: TextDirection.ltr, 
        child: Container(width: 90, height: 90, color: Colors.green.withOpacity(0.6))));
return Container(height: 180, width: 180, color: Colors.redAccent.withOpacity(0.4),
    child: UnconstrainedBox(constrainedAxis: null,
        alignment: AlignmentDirectional(-1.0, -1.0), textDirection: TextDirection.rtl,
        child: Container(width: 100, height: 100, color: Colors.purple.withOpacity(0.6))));

3. constrainedAxis

      作用于是否保留约束的轴方向,若不设置或设置为 null 则横向或纵向均不保留约束;若设置为 vertical 则保留其父类纵向约束;设置为 horizontal 则保留其父类横向约束;

return Container(height: 100, width: 360, color: Colors.blueAccent.withOpacity(0.4),
    child: UnconstrainedBox(alignment: Alignment.center, constrainedAxis: null,
        child: Container(width: 80, height: 80, color: Colors.green.withOpacity(0.6))));
return Container(height: 100, width: 360, color: Colors.blueAccent.withOpacity(0.4),
    child: UnconstrainedBox(alignment: Alignment.center, constrainedAxis: Axis.vertical,
        child: Container(width: 100, height: 300, color: Colors.green.withOpacity(0.6))));
return Container(height: 100, width: 360, color: Colors.blueAccent.withOpacity(0.4),
    child: UnconstrainedBox(alignment: Alignment.topRight, constrainedAxis: Axis.horizontal,
        child: Container(width: 100, height: 300, color: Colors.green.withOpacity(0.6))));
return Container(height: 100, width: 360, color: Colors.blueAccent.withOpacity(0.4),
    child: UnconstrainedBox(alignment: Alignment.topLeft, constrainedAxis: null,
        child: Container(width: 100, height: 300, color: Colors.green.withOpacity(0.6))));

LimitedBox

源码分析

class LimitedBox extends SingleChildRenderObjectWidget {
  const LimitedBox({
    Key key,
    this.maxWidth = double.infinity,    // 最大宽度
    this.maxHeight = double.infinity,   // 最大高度
    Widget child,
  })
}

      分析源码可知,LimitedBox 主要是在不受父 Widget 限制时,通过 maxHeight / maxWidth 对子 Widget 的约束,且 maxHeight / maxWidth 必须 >= 0.0;

案例尝试

      小菜分如下几个场景进行尝试

  1. LimitedBoxWidget 无限制,子 Widget 宽高小于约束最大宽高;
return Container(child: LimitedBox(maxWidth: 100, maxHeight: 100, child: Container(width: 80, height: 80, color: Colors.purple.withOpacity(0.4))));

  1. LimitedBoxWidget 无限制,子 Widget 宽高大于约束最大宽高;
return Container(child: LimitedBox(maxWidth: 100, maxHeight: 100, child: Container(width: 160, height: 160, color: Colors.orange.withOpacity(0.4))));

  1. LimitedBoxWidget 有限制时;无论 LimitedBox 设置限制最大宽高和子 Widget 宽高,均以父 Widget 宽高为准;
return Container(width: 200, height: 80, child: LimitedBox(maxWidth: 100, maxHeight: 100, child: Container(width: 160, height: 160, color: Colors.orange.withOpacity(0.4))));

FractionallySizedBox

源码分析

class FractionallySizedBox extends SingleChildRenderObjectWidget {
  const FractionallySizedBox({
    Key key,
    this.alignment = Alignment.center,  // 对齐方式
    this.widthFactor,                   // 宽度因子
    this.heightFactor,                  // 高度因子
    Widget child,
  })
}

      分析源码可知,FractionallySizedBox 可以通过对齐方式和设置宽高因子并结合父 Widget 宽高来约束子 Widget;采用宽高因子使用更加灵活;

案例尝试

1. alignment

      与其他组件相同,通用于子 Widget 的对齐方向;

2. widthFactor

      宽度因子,若不为 null 则通过父 Widget 宽度占比来约束子 Widget 宽度;若为 null 按照父 Widget 宽度填充;

3. heightFactor

      高度因子,与 widthFactor 使用相同;

return Container(color: Colors.blueAccent.withOpacity(0.4), width: 100, height: 100,
    child: FractionallySizedBox(alignment: Alignment.center, widthFactor: 0.5, heightFactor: 0.5,
        child: Container(width: 50, height: 80, color: Colors.orange.withOpacity(0.6))));
return Container(color: Colors.blueAccent.withOpacity(0.4), width: 100, height: 100,
    child: FractionallySizedBox(alignment: Alignment.center, widthFactor: 0.5, heightFactor: null,
        child: Container(width: 200, height: 200, color: Colors.orange.withOpacity(0.6))));
return Container(color: Colors.blueAccent.withOpacity(0.4), width: 100, height: 100,
    child: FractionallySizedBox(alignment: Alignment.center, widthFactor: 1.5, heightFactor: 0.6,
        child: Container(color: Colors.orange.withOpacity(0.6))));
return Container(color: Colors.blueAccent.withOpacity(0.4), width: 100, height: 100,
    child: FractionallySizedBox(alignment: AlignmentDirectional(-0.15, -0.15), widthFactor: 0.5, heightFactor: 0.5,
        child: Container(color: Colors.orange.withOpacity(0.6))));

FittedBox

源码分析

class FittedBox extends SingleChildRenderObjectWidget {
  const FittedBox({
    Key key,
    this.fit = BoxFit.contain,          // 填充方式
    this.alignment = Alignment.center,  // 对齐方式
    Widget child,
  })
}

      分析源码可知,FittedBox 主要通过 fit 填充方式和 alignment 对齐方式对子 Widget 进行约束;且 fit / alignment 不可为空,对于图片的裁剪很有效;

案例尝试

      FittedBox 主要是通过 BoxFit 填充方式与 alignment 对齐方式共同约束子 Widget

  1. BoxFit.fill 通过子 Widget 拉伸或压缩填充满父 Widget
  2. BoxFit.contain 通过子 Widget 比例拉伸或压缩,直到宽或高一边填充父 Widget
  3. BoxFit.cover 以子 Widget 宽或高填充父 Widget,剩余一边若超过父 Widget 对应边则裁切;
  4. BoxFit.fitWidth 通过子 Widget 以宽为基准填充父 Widget,若高度超出会被裁切,子 Widget 不拉伸或压缩;
  5. BoxFit.fitHeight 通过子 Widget 以高为基准填充父 Widget,若宽度超出会被裁切,子 Widget 不拉伸或压缩;
  6. BoxFit.noneWidget 不拉伸或压缩,若超出父 Widget 则被裁切;
  7. BoxFit.scaleDown 若子 Widget 可以完全放在父 Widget 中则与 BoxFit.none 效果一致;若子 Widget 不能完全放在父 Widget 中则与 BoxFit.contain 效果一致;
return Container(width: 100, height: 100, color: Colors.blueAccent.withOpacity(0.4),
    child: FittedBox(fit: BoxFit.cover, alignment: Alignment.topCenter, child: Image.asset("images/icon_hzw02.jpg")));
return Container(width: 100, height: 100, color: Colors.blueAccent.withOpacity(0.4),
    child: FittedBox(fit: BoxFit.fill, alignment: Alignment.topCenter, child: Image.asset("images/icon_hzw02.jpg")));
return Container(width: 100, height: 100, color: Colors.blueAccent.withOpacity(0.4),
    child: FittedBox(fit: BoxFit.fitHeight, alignment: Alignment.topCenter, child: Image.asset("images/icon_hzw02.jpg")));
return Container(width: 100, height: 100, color: Colors.blueAccent.withOpacity(0.4),
    child: FittedBox(fit: BoxFit.none, alignment: Alignment.center, child: Image.asset("images/icon_hzw02.jpg")));


      Flutter 提供了多种约束 Box 方式,基本都是继承自 SingleChildRenderObjectWidget,每种 Box 有各自特点,合理利用可以大大提高开发效率;小菜对 Box 的学习还不完整,有错误的地方请多多指导!

来源: 阿策小和尚

目录
相关文章
|
3月前
|
容器
Flutter笔记:Box协议的布局约束原理与应用
Flutter笔记:Box协议的布局约束原理与应用
48 0
|
算法 容器
flutter 约束(constrains )实例研究(下)
flutter 约束(constrains )实例研究(下)
121 0
flutter 约束(constrains )实例研究(下)
|
Web App开发 前端开发 Go
flutter 约束(constrains )实例研究(上)
flutter 约束(constrains )实例研究
98 0
flutter 约束(constrains )实例研究(上)
flutter系列之:把box布局用出花来
flutter中的layout有很多,基本上看layout的名字就知道这个layout到底是做什么用的。比如说这些layout中的Box,从名字就知道这是一个box的布局,不过flutter中的box还有很多种,今天我们来介绍最常用的LimitedBox,SizedBox和FittedBox。
flutter系列之:把box布局用出花来
|
容器
Flutter 68: 图解基本约束 Box (三)
0 基础学习 Flutter,第六十八步:学习以下基本约束 Box (三)!
1206 0
|
容器 存储
Flutter 66: 图解基本约束 Box (一)
0 基础学习 Flutter,第六十六步:学习一下基本约束盒子 (一)!
1272 0
|
3月前
|
监控 Dart 安全
创建一个Dart应用,监控局域网上网记录的软件:Flutter框架的应用
在当今数字时代,网络安全变得愈发重要。为了监控局域网上的上网记录,我们可以借助Flutter框架创建一个强大的Dart应用。在这篇文章中,我们将深入讨论如何使用Flutter框架开发这样一个监控局域网上网记录的软件,并提供一些实用的代码示例。
275 1
|
6月前
|
Dart Android开发 UED
带你读《深入浅出Dart》二十七、Flutter路由管理
带你读《深入浅出Dart》二十七、Flutter路由管理
|
2月前
|
Dart JavaScript
Flutter - Dart 基础(数据类型)
【2月更文挑战第3天】
66 1
|
2月前
|
Dart JavaScript 安全