flutter系列之:永远不用担心组件溢出的Wrap

简介: 我们在flutter中使用能够包含多个child的widget的时候,经常会遇到超出边界范围的情况,尤其是在Column和Row的情况下,那么我们有没有什么好的解决办法呢?答案就是今天我们要讲解的Wrap。

简介

我们在flutter中使用能够包含多个child的widget的时候,经常会遇到超出边界范围的情况,尤其是在Column和Row的情况下,那么我们有没有什么好的解决办法呢?答案就是今天我们要讲解的Wrap。

Row和Column的困境

Row和Column中可以包含多个子widget,如果子widget超出了Row或者Column的范围会出现什么情况呢?

我们以Row的情况举个例子:

Widget build(BuildContext context) {
    return Row(
      textDirection: TextDirection.ltr,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        YellowBox(),
        YellowBox(),
        Expanded(
          child: YellowBox(),
        ),
        YellowBox(),
      ],
    );
  }

上面的例子中,我们在Row中添加了几个YellowBox,YellowBox是一个width=100,height=50的长方形:

Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 50,
      decoration: BoxDecoration(
        color: Colors.yellow,
        border: Border.all(),
      ),
    );
  }

运行上面的代码,我们可以得到这样的界面:

如果在Row中多添加几个YellowBox会有什么效果呢?

我们在上面的Row中多添加一个yellowBox:

Widget build(BuildContext context) {
    return Row(
      textDirection: TextDirection.ltr,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        YellowBox(),
        YellowBox(),
        Expanded(
          child: YellowBox(),
        ),
        YellowBox(),
        YellowBox(),
      ],
    );
  }

运行可以得到下面的界面:

可以看到,因为Row中的子widget太多了,已经超出了Row的范围,界面上已经报错了。

要解决这个问题,就需要使用到Wrap组件。

Wrap组件详解

先来看下Wrap的定义:

class Wrap extends MultiChildRenderObjectWidget

Wrap继承自MultiChildRenderObjectWidget,表示可以包含多个子child。

接下来是Wrap的构造函数:

Wrap({
    Key? key,
    this.direction = Axis.horizontal,
    this.alignment = WrapAlignment.start,
    this.spacing = 0.0,
    this.runAlignment = WrapAlignment.start,
    this.runSpacing = 0.0,
    this.crossAxisAlignment = WrapCrossAlignment.start,
    this.textDirection,
    this.verticalDirection = VerticalDirection.down,
    this.clipBehavior = Clip.none,
    List<Widget> children = const <Widget>[],
  }) : assert(clipBehavior != null), super(key: key, children: children);

构造函数中列出了Wrap中常用的属性。

其中direction表示子组件的排列方向。alignment表示的是子组件的对其方式。spacing表示子组件的间隔。

跟spacing类似的还有一个runSpacing属性,两者有什么区别呢? 我们还是通过一个具体的例子来查看。

Widget build(BuildContext context) {
    return Wrap(
      direction: Axis.horizontal,
      textDirection: TextDirection.ltr,
      children: [
        YellowBox(),
        YellowBox(),
        // Expanded(
        //   child: YellowBox(),
        // ),
        YellowBox(),
        YellowBox(),
        YellowBox(),
      ],
    );

还是上面的例子,这里我们使用Wrap来替换Row,这里我们使用了direction选项,表示是在横向方向进行Wrap。

然后在children中添加了5个YellowBox。

注意,这里不能使用Expanded,否则会报错,所以我们把Expanded注释掉了,运行可以得到下面的界面:

可以看到YellowBox是按行的方向来排列的,超出一行的范围之后就会自动换行,这也就是Wrap的功能。

我们在讲解Wrap的时候,还提到了两个属性,分别是spacing和runSpacing。两者有什么区别呢?

先看下spacing:

Widget build(BuildContext context) {
    return Wrap(
      direction: Axis.horizontal,
      spacing: 10,
      textDirection: TextDirection.ltr,
      children: [
        YellowBox(),
        YellowBox(),
        // Expanded(
        //   child: YellowBox(),
        // ),
        YellowBox(),
        YellowBox(),
        YellowBox(),
      ],
    );
  }

我们先给Wrap添加spacing属性,运行可以得到下面的界面:

可以看到YellowBox之间是用spacing来进行分割的。

那么如果我们希望在Wrap换行的时候,两行之间也有一些间距应该怎么处理呢?

这个时候就需要用到runSpacing属性了:

Widget build(BuildContext context) {
    return Wrap(
      direction: Axis.horizontal,
      spacing: 10,
      runSpacing: 10,
      textDirection: TextDirection.ltr,
      children: [
        YellowBox(),
        YellowBox(),
        // Expanded(
        //   child: YellowBox(),
        // ),
        YellowBox(),
        YellowBox(),
        YellowBox(),
      ],
    );
  }

运行可以得到下面的界面:

Wrap已经完美的运行了。

总结

Wrap可以通过使用不同的direction来替换Row或者Column,我们在组件可能会超出范围的时候,就可以考虑使用Wrap了。

本文的例子:https://github.com/ddean2009/learn-flutter.git

更多内容请参考 www.flydean.com

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

相关文章
|
2月前
|
传感器 缓存 监控
Stream 组件在 Flutter 中的应用场景有哪些?
Stream 组件在 Flutter 中的应用场景有哪些?
177 58
|
2月前
|
UED 开发者
Flutter|常用数据通信组件
Flutter|常用数据通信组件
103 49
|
19天前
Flutter 自定义组件继承与调用的高级使用方式
本文深入探讨了 Flutter 中自定义组件的高级使用方式,包括创建基本自定义组件、继承现有组件、使用 Mixins 和组合模式等。通过这些方法,您可以构建灵活、可重用且易于维护的 UI 组件,从而提升开发效率和代码质量。
115 1
|
19天前
|
开发工具 UED
Flutter&鸿蒙next中封装一个输入框组件
本文介绍了如何创建一个简单的Flutter播客应用。首先,通过`flutter create`命令创建项目;接着,在`lib`目录下封装一个自定义输入框组件`CustomInput`;然后,在主应用文件`main.dart`中使用该输入框组件,实现简单的UI布局和功能;最后,通过`flutter run`启动应用。本文还提供了后续扩展建议,如状态管理、网络请求和UI优化。
97 1
|
23天前
|
Dart UED
Flutter用户交互组件
Flutter用户交互组件
20 2
|
1月前
|
存储 开发框架 开发者
flutter:代码存储&基本组件 (五)
本文档介绍了Flutter中的一些基本组件和代码示例,包括代码存储、基本组件如AppBar的简单使用、可滑动切换的标签栏、TextField的多种用法(如简单使用、登录页面、文本控制器的监听与使用、修饰等),以及如何实现点击空白区域隐藏键盘等功能。通过这些示例,开发者可以快速掌握在Flutter应用中实现常见UI元素的方法。
|
18天前
|
开发工具
Flutter&鸿蒙next中封装一个列表组件
Flutter&鸿蒙next中封装一个列表组件
32 0
|
2月前
|
开发者
Flutter|常用数据通信组件
Flutter|常用数据通信组件
|
2月前
Stream 组件在 Flutter 中的具体使用方法是什么?
Stream 组件在 Flutter 中的具体使用方法是什么?
|
1月前
|
开发者
flutter:功能性组件 (八)
本文介绍了Flutter中常用的UI组件和功能,包括进度指示器(线性和圆形)、下拉刷新、选项按钮(单选按钮、复选框、开关)、手势识别(GestureDetector、Ink和InkWell)以及提示和Offstage组件的使用方法和示例代码。这些组件和功能可以帮助开发者快速构建交互丰富的应用程序界面。