前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter 专题】67 图解基本约束 Box (二)

【Flutter 专题】67 图解基本约束 Box (二)

作者头像
阿策小和尚
发布2019-11-12 21:40:49
5210
发布2019-11-12 21:40:49
举报
文章被收录于专栏:阿策小和尚阿策小和尚

和尚继续学习约束 Box 的各类应用;

UnconstrainedBox

源码分析
代码语言:javascript
复制
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 用于从左到右或从右到左的起始方向;

代码语言:javascript
复制
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 则保留其父类横向约束;

代码语言:javascript
复制
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

源码分析
代码语言:javascript
复制
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 宽高小于约束最大宽高;
代码语言:javascript
复制
return Container(child: LimitedBox(maxWidth: 100, maxHeight: 100, child: Container(width: 80, height: 80, color: Colors.purple.withOpacity(0.4))));
  1. LimitedBoxWidget 无限制,子 Widget 宽高大于约束最大宽高;
代码语言:javascript
复制
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 宽高为准;
代码语言:javascript
复制
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

源码分析
代码语言:javascript
复制
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 使用相同;

代码语言:javascript
复制
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

源码分析
代码语言:javascript
复制
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 效果一致;
代码语言:javascript
复制
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 的学习还不完整,有错误的地方请多多指导!

来源:阿策小和尚

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿策小和尚 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • UnconstrainedBox
    • 源码分析
      • 案例尝试
        • 1. alignment
        • 2. textDirection
        • 3. constrainedAxis
    • LimitedBox
      • 源码分析
        • 案例尝试
        • FractionallySizedBox
          • 源码分析
            • 案例尝试
              • 1. alignment
              • 2. widthFactor
              • 3. heightFactor
          • FittedBox
            • 源码分析
              • 案例尝试
              相关产品与服务
              文件存储
              文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档