Flutter布局(3):流式布局(Wrap、Flow)

 


一、简介

在 Flutter 中,流式布局是一种常用的布局方式,用于实现动态调整子组件位置和尺寸的需求。

Flutter 提供了两个流式布局的组件:WrapFlow

其实,Flow 用的实在不多呀。

二、Wrap组件

Wrap 组件是一种流式布局,它会自动调整和换行子组件,以适应可用空间。

属性

Wrap 组件具有以下常见属性:

  • direction(方向):指定子组件的排列方向,可以是水平(Axis.horizontal)或垂直(Axis.vertical)方向。
  • alignment(对齐方式):指定子组件在主轴上的对齐方式。
  • spacing(主轴间距):指定子组件在主轴上的间距。
  • runSpacing(交叉轴间距):指定子组件在交叉轴上的间距。

Wrap 使用场景

  • 动态排列:当子组件的数量不确定或需要动态添加时,使用Wrap可以自动调整子组件的位置和尺寸,以适应可用空间。
  • 标签布局:在实现标签云、标签选择器等场景时,Wrap组件非常有用。子组件可以根据可用空间自动换行,并根据内容自适应尺寸。

下面是一个可运行的示例代码,展示了 Wrap 组件的基本用法:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Wrap布局示例'),
        ),
        body: const Wrap(
          direction: Axis.horizontal,
          alignment: WrapAlignment.start,
          spacing: 8.0,
          runSpacing: 8.0,
          children: <Widget>[
            Chip(
              label: Text('标签1'),
              backgroundColor: Colors.blue,
            ),
            Chip(
              label: Text('标签2'),
              backgroundColor: Colors.green,
            ),
            Chip(
              label: Text('标签3'),
              backgroundColor: Colors.red,
            ),
            // 更多子组件...
          ],
        ),
      ),
    );
  }
}

在这个例子中,Wrap 组件包含了一些 Chip 组件作为子组件。Wrap 的属性设置了子组件的排列方向、对齐方式以及主轴和交叉轴的间距。效果图如下所示:

Flutter_layoutWidget_N.png


三、Flow组件

属性

Flow 组件也是一种流式布局,它与 Wrap 不同的是,Flow 可以更精确地控制子组件的位置。Flow 组件具有以下常见属性:

  • delegate(委托):FlowDelegate 对象,用于控制子组件的位置和尺寸。

Flow使用场景

Flow 组件在开发中常用于以下场景:

  1. 自定义布局:当需要自定义子组件的位置时,可以使用 Flow 组件。通过自定义 FlowDelegate 对象,可以实现灵活的布局算法。
  2. 复杂布局:在一些复杂的布局需求中,Flow 可以提供更精确的控制,例如创建非线性的子组件排列方式。

下面是一个可运行的示例代码,展示了 Flow 组件的基本用法:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flow布局示例'),
        ),
        body: Flow(
          delegate: FlowChildrenDelegate(
            margin: const EdgeInsets.all(10.0),
          ),
          children: <Widget>[
            Container(width: 80.0, height: 80.0, color: Colors.red),
            Container(width: 120.0, height: 80.0, color: Colors.green),
            Container(width: 100.0, height: 100.0, color: Colors.blue),
            // 更多子组件...
          ],
        ),
      ),
    );
  }
}

class FlowChildrenDelegate extends FlowDelegate {
  final EdgeInsets margin;

  FlowChildrenDelegate({required this.margin});

  @override
  void paintChildren(FlowPaintingContext context) {
    for (int i = 0; i < context.childCount; i++) {
      context.paintChild(
        i,
        transform: Matrix4.translationValues(
          margin.left + (i % 3) * (80.0 + margin.left + margin.right),
          margin.top + (i ~/ 3) * (80.0 + margin.top + margin.bottom),
          0.0,
        ),
      );
    }
  }

  @override
  bool shouldRepaint(covariant FlowDelegate oldDelegate) {
    return true;
  }
}

在这个例子中,Flow 组件包含了一些 Container 组件作为子组件。Flow 的 delegate 属性使用了自定义的 FlowDelegate 对象来控制子组件的位置和尺寸。

看起来,是复杂了点。实际使用频率也不是很高。

效果图如下所示:

Flutter_layoutWidget_O.png


四、总结

Wrap 和 Flow 是 Flutter 中常用的流式布局组件,它们可以帮助我们实现动态调整子组件位置和尺寸的需求。Wrap 适用于自动换行和自适应尺寸的场景,而 Flow 适用于更精确控制子组件位置的场景。


posted @   fengMisaka  阅读(489)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示