Flutter 68: 图解基本约束 Box (三)

作者: 阿策神奇 | 来源:发表于2019-11-13 09:18 被阅读0次

          小菜对约束 Box 探索之路还在继续,小菜今天主要学习一下 Overflow 相关 Box

    OverflowBox

    源码分析

    class OverflowBox extends SingleChildRenderObjectWidget {
      const OverflowBox({
        Key key,
        this.alignment = Alignment.center,  // 对齐方式
        this.minWidth,                      // 允许最小宽度
        this.maxWidth,                      // 允许最大宽度
        this.minHeight,                     // 允许最小高度
        this.maxHeight,                     // 允许最大高度
        Widget child,
      })
    }
    

          分析源码可得,OverflowBox 通过设置最大最小宽高对子 Widget 进行约束,且与父 Widget 相关,子 Widget 可能会溢出父 Widget

    案例尝试

          小菜通过如下几种场景探索 OverflowBox 与父 Widget 和子 Widget 的关联关系,其中 alignment 是通用的对齐方式,不在此单独说明;由于 OverflowBox 允许子 Widget 溢出父 Widget,很多朋友用此实现自定义 Dialog

    1. Widget 无约束,仅设置 minWidth / minHeight,子 Widget 宽高小于等于 OverflowBox 最小宽高;此时 child.width <= minWidth && child.height <= minHeight,最终以 OverflowBox 设置的最小宽高约束子 Widget
    return Container(color: Colors.blueAccent.withOpacity(0.4),
        child: OverflowBox(alignment: Alignment.center, minHeight: 100,
            child: Container(color: Colors.purple.withOpacity(0.4), width: 50, height: 50)));
    
    1. Widget 无约束,仅设置 minWidth / minHeight,子 Widget 宽高大于 OverflowBox 最小宽高;此时 minWidth < child.width < maxWidth,最终以子 Widget 设置的宽高展示;
     return Container(color: Colors.green.withOpacity(0.4),
        child: OverflowBox(alignment: Alignment.center, minHeight: 100, minWidth: 100,
            child:Container(color: Colors.purple.withOpacity(0.4), width: 150, height: 150)));
    
    1. Widget 无约束,设置 maxWidth / maxHeight,若 child.width > maxWidth || child.height > maxHeight 则以 OverflowBox 设置的最大宽高约束子 Widget;若 child.width < maxWidth && child.height < maxHeight 则按照上述两种情况进行约束;
    return Container(color: Colors.orange.withOpacity(0.4),
        child: OverflowBox(alignment: Alignment.center,
            minHeight: 100, maxWidth: 150, maxHeight: 150,
            child: Container(color: Colors.purple.withOpacity(0.4), width: 50, height: 50)));
    return Container(color: Colors.grey.withOpacity(0.4),
        child: OverflowBox(alignment: Alignment.center,
            minHeight: 100, minWidth: 100, maxWidth: 150, maxHeight: 150,
            child: Container(color: Colors.purple.withOpacity(0.4), width: 200, height: 200)));
    
    1. Widget 有约束,设置 maxWidth > parent.width || maxHeight > parent.height,此时允许子 Widget 宽高大于父 Widget 宽高,其约束方式与上述情况相同;
    return Container(width: 200, height: 200, color: Colors.brown.withOpacity(0.4),
        child: OverflowBox(alignment: Alignment.center,
            minHeight: 100, minWidth: 50, maxHeight: 250, maxWidth: 250,
            child: Container(color: Colors.purple.withOpacity(0.4))));
    
    1. 对于大部分涉及最大最小宽高的 Widget,最小宽高均不允许大于最大宽高,使用时请注意;
    return Container(width: 200, height: 200, color: Colors.brown.withOpacity(0.4),
        child: OverflowBox(alignment: Alignment.center,
            minHeight: 250, minWidth: 50,
            child: Container(color: Colors.purple.withOpacity(0.4))));
    

    SizedOverflowBox

    源码分析

    class SizedOverflowBox extends SingleChildRenderObjectWidget {
      const SizedOverflowBox({
        Key key,
        @required this.size,                // 约束 Size
        this.alignment = Alignment.center,  // 对齐方式
        Widget child,
      })
    }
    

          分析源码可知,SizedOverflowBoxSizedBoxOverflowBox 的结合,小菜简单理解 SizedBox 设置基本约束,OverflowBox 设置子 Widget 与父 Widget 关系,是否溢出;

    案例尝试

          size 是对子 Widget 的基本尺寸约束,alignment 是通用的对齐方式,小菜按如下场景进行尝试;

    1. Widget 无约束,若 child.width <= Size.x && child.height <= Size.y,以子 Widget 宽高约束展示;
    return Container(color: Colors.green.withOpacity(0.4),
        child: Center(child: SizedOverflowBox(
            size: Size(100, 100), alignment: Alignment.center,
            child: Container(width: 50, height: 50, color: Colors.blueAccent.withOpacity(0.6)))));
    
    1. Widget 无约束,若 child.width > Size.x || child.height > Size.h,以子 Widget 宽高溢出展示;
    return Container(color: Colors.orange.withOpacity(0.4),
        child: Center(child: SizedOverflowBox(
            size: Size(100, 100), alignment: Alignment.center,
            child: Container(width: 150, height: 150, color: Colors.purple.withOpacity(0.4)))));
    
    1. Widget 有约束时,若 child.width <= Size.x && child.height <= Size.y 时,与状况一相同;若 child.width > parent.width >= Size.x || child.height > parent.height >= Size.y,则子 Widget 溢出 SizedOverflowBox 到父 Widget 约束宽高展示;
    return Container(width: 150, height: 150, color: Colors.redAccent.withOpacity(0.4),
        child: Center(child: SizedOverflowBox(
            size: Size(100, 100), alignment: Alignment.center,
            child: Container(width: 250, height: 50, color: Colors.grey.withOpacity(0.8)))));
    
    1. Widget 有约束时,若 Size.x > parent.width || Size.y > parent.height,最终展示的最大宽高是父 Widget 约束的宽高(子 Widget 溢出或非溢出);
    return Container(width: 150, height: 150, color: Colors.redAccent.withOpacity(0.4),
        child: Center(child: SizedOverflowBox(
            size: Size(400, 400), alignment: Alignment.topLeft,
            child: Container(width: 150, height: 50, color: Colors.grey.withOpacity(0.8)))));
    

    小理解

          小菜尝试了诸多约束 Box,甚至有些 Box 在使用和功能上大同小异,相同的功能,可以用其他的 Widget 来实现但为什么要有这么多约束 Box

          小菜对此理解还不够深入,仅简单的交流个人理解,如有错误请多多指导!对于常用的 SizedBox 既可以用作约束盒子也可以作为空间占位符,对此 Container 完全可以实现,还可以实现很多复杂效果;SizedBox 存在的理由:小菜认为一是 SizedBox 功能更单一,相对于 Container 性能更好(Flutter 渲染性能很高,可以忽略不计);二是 SizedBox 功能性更加清晰明确;合理利用各 Widget 会让编码更加清晰高效;


          小菜对约束 Box 的探索暂时到此,希望大家可以对各类 Box 多多尝试!

    来源: 阿策小和尚

    相关文章

      网友评论

        本文标题:Flutter 68: 图解基本约束 Box (三)

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