assorted_layout_widgets

Flutter 包:各种布局小部件,它们大胆地探索了原生 Flutter 小部件尚未触及的领域。

此包中的小部件

  • ColumnSuper
  • RowSuper
  • FitHorizontally
  • Box
  • TextOneLine

我将缓慢但稳步地向此包添加有趣的小部件。

ColumnSuper

给定子小部件列表,它将它们排列在列中。
它可以重叠单元格,添加分隔符等等。

ColumnSuper({  
    List<Widget> children,    
    double outerDistance,
    double innerDistance,
    bool invert,
    Alignment alignment,
    Widget separator,
    bool separatorOnTop,
  });

columnSuper

  • children 是代表列单元格的小部件列表,就像常规的Column小部件一样。
    但是,列表可能包含null,这些将被忽略。

  • outerDistance 是第一个和小部件之前的距离(以像素为单位)。
    它可以是负数,在这种情况下,单元格将溢出列。

  • innerDistance 是单元格之间的距离(以像素为单位)。
    它可以是负数,在这种情况下,单元格将重叠。

  • invert 如果为true,则会将较后的单元格绘制在先前的单元格之上。
    这在单元格重叠时(负的innerDistance)特别有用。

  • alignment 如果单元格小于可用水平空间,它将水平对齐单元格。

  • separator 是一个将在每个单元格之间放置的小部件。其高度无关紧要,
    因为单元格之间的距离由innerDistance给出(换句话说,分隔符不占用空间)。
    如果分隔符的宽度大于列的宽度,它将溢出。

  • separatorOnTop 如果为true(默认值),它将在单元格之上绘制分隔符。
    如果为false,它将在单元格之下绘制分隔符。

注意:这不是Flutter原生Column的替代品,
它不试图拥有类似的API,也不具备Column的所有功能。
特别地,ExpandedFlexible小部件不能在ColumnSuper内部使用,
并且如果列不够大以容纳其内容,它将溢出。
ColumnSuper仅用于Column不起作用的某些用例,
例如需要重叠单元格时。

尝试运行ColumnSuper示例

RowSuper

给定子小部件列表,它将它们排列在行中。
它可以重叠单元格,添加分隔符等等。

RowSuper({  
    List<Widget> children,    
    double outerDistance,
    double innerDistance,
    bool invert,
    Alignment alignment,
    Widget separator,
    bool separatorOnTop,
    bool fitHorizontally,
    double shrinkLimit,
    MainAxisSize mainAxisSize,
  });

ColumnSuper和原生Row不同
(如果单元格不够大以容纳其内容,它将溢出),
RowSuper将根据每个单元格内容的最小固有宽度按比例调整其单元格大小

尝试运行RowSuper示例

大多数参数与ColumnSuper的参数相同,除了

  • fitHorizontally 如果为true,它将仅水平调整单元格内容的大小,直到达到shrinkLimit

  • shrinkLimit 默认值为67%,这意味着单元格内容将缩小到其原始宽度的67%,
    然后溢出。如果希望单元格内容无限制地缩小,请将shrinkLimit设置为0.0
    请注意,如果fitHorizontally为false,则不使用shrinkLimit

  • mainAxisSize 默认为MainAxisSize.min,这意味着行将占用不超过其内容宽度的空间。
    将其设置为MainAxisSize.max以扩展行以占用整个水平空间。

您还可以使用RowSpacer在单元格之间添加空白(如果可用)。例如

RowSuper(
   children: [
      widget1, 
      RowSpacer(), 
      widget2, 
      widget3,
      ]
   )
);   

rowSuperWithFirHorizontally

尝试运行具有FitHorizontally的RowSuper示例

注意:这不是Flutter原生Row的替代品,
它不试图拥有类似的API,也不具备Row的所有功能。
特别地,ExpandedFlexible小部件不能在RowSuper内部使用,
因为当内容不合适时,RowSuper会按比例调整单元格大小。
RowSuper仅用于Row不起作用的某些用例,
例如需要重叠单元格,或者需要在内容不合适时缩放单元格的
内容。

FitHorizontally

FitHorizontally({
    Widget child,  
    double shrinkLimit,
    bool fitsHeight,
    AlignmentGeometry alignment,
  });

fitHorizontally

将要求child定义其自身的固有高度。
如果fitsHeight为true,则将按比例调整子项的大小(保持其纵横比)
以适应可用高度。

然后,如果子项不适合宽度,它将被水平缩小
(不保持其纵横比),直到其适合为止,除非shrinkLimit大于零,
在这种情况下,它只会缩小到该限制。
请注意,如果shrinkLimit为1.0,则子项
将不会缩小。默认值为0.67(67%)。

这对于显示为单行的文本特别有用。
当文本不适合容器时,它将仅水平缩小,
直到达到收缩限制。从那时起,它将根据文本的Text.overflow属性进行剪裁、
显示省略号或渐变。

注意:FitHorizontallyshrinkLimit 0.0 等同于FittedBoxBoxFit.fitWidth
因为FitHorizontally仅进行水平缩放,而FittedBox会保持纵横比。

尝试运行FitHorizontally示例

Box

Box介于ContainerSizedBox之间,它更简洁,并且可以设为const

const Box({
    bool show,
    Color color,
    double top,
    double right,
    double bottom,
    double left,
    double vertical,
    double horizontal,
    double width,
    double height,
    Alignment alignment,
    Widget child,
  });

由于它可以设为const,因此非常适合创建彩色框,
带或不带子项和内边距

const Box(color: Colors.red, width: 50, height:30);

内边距由toprightbottomleft值给出,但它们
仅在子项不为null时应用。
如果childwidthheight都为null,这意味着框将不占用任何空间(将被
隐藏)。注意:这将在未来扩展,以便当子项宽度为零时忽略水平
内边距,当子项高度为零时忽略垂直
内边距。

如果topbottom相等,则可以改为提供vertical

// This:
const Box(top: 20, bottom:20, child: ...);

// Is the same as this:
const Box(vertical: 20, child: ...);

您不能同时提供verticaltopbottom

同样,如果rightleft相等,则可以改为提供horizontal
您不能同时提供horizontalrightleft

您也可以通过将show参数设置为false来隐藏该框。

简洁代码

Box可以用作Padding的更简洁的替代品。例如,此代码

return Container(
    padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
    color: Colors.green,
    child: const Padding(
      padding: EdgeInsets.only(top: 12.0, bottom: 12.0, left: 4.0),      
      child: Text("Hello."),
    ),
  ),
);

与其功能等效

return const Box(
    vertical: 8.0,
    horizontal: 5.0,      
    color: Colors.green,
    child: Box(vertical: 12.0, left: 4.0, child: Text("Hello.")),
);

调试

  • 如果您需要快速临时为框添加颜色以便看到它,
    可以使用构造函数Box.r表示红色,Box.g表示绿色,Box.b表示蓝色,Box.y表示黄色。

    Box(child: myChild);
    Box.r(child: myChild);
    Box.g(child: myChild);
    Box.b(child: myChild);
    Box.y(child: myChild);
    
  • 如果您想查看重建,可以使用Box.rand构造函数。
    它将在每次调用其build方法时将其颜色更改为随机颜色。

    Box.rand(child: myChild);  
    

TextOneLine

TextOneLineTextmaxLines: 1时的替代品,以解决此问题
https://github.com/flutter/flutter/issues/18761 由我很久以前提交。

它使用一种特殊的渐变省略号,
比当前有bug且外观丑陋的省略号(会截断整个单词)要好得多。

例如,这个

Text("This isAVeryLongWordToDemonstrateAProblem", maxLines: 1, softWrap: false);  

将在屏幕上打印此内容

This ...  

而这个

TextOneLine("This isAVeryLongWordToDemonstrateAProblem");  

将打印此内容

This isAVeryLongWordToDemonst...  

该小部件可能只有在问题未解决时才有意义。

AlignPositioned

请参阅包 align_positioned
用于AlignPositioned小部件及其同级AnimatedAlignPositionedAnimChain
它们应该属于此包,但由于历史原因将保留在其自己的包中。

GitHub

https://github.com/marcglasberg/assorted_layout_widgets