Flutter列表项自动换行插件extended_wrap的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter列表项自动换行插件extended_wrap的使用

描述

Extended Wrap是在Flutter中用于创建特殊Wrap布局的插件,比如限制行数等。它扩展了官方的Wrap组件,为开发者提供了更多定制化选项。

功能特性

  • maxLines: 设置最大行数,默认值为1。
  • minLines: 当收缩状态时必须等于maxLines,默认值为1。
  • overflowWidget: 用于控制超出部分的显示和隐藏,默认无。

使用方法

添加依赖

首先,在pubspec.yaml文件中添加extended_wrap依赖:

dependencies:
  flutter:
    sdk: flutter
  extended_wrap: ^latest_version # 请替换为最新版本号

然后执行flutter pub get以安装依赖。

示例代码

下面是一个完整的示例demo,展示了如何使用extended_wrap创建一个可以展开和收缩的标签云效果:

import 'package:extended_wrap/extended_wrap.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> resultList = [
    "穿搭冬季",
    "2021秋冬流行穿搭",
    "穿搭",
    "家常菜",
    "文案",
    "头像",
    "健身",
    "学习",
    "跟井柏然学花衬衫叠穿",
    "准备好圣诞礼物了吗",
    "哈利波特手游雪山来客攻略",
    "人间富贵花穿搭"
  ];

  int minLines = 2;
  int maxLines = 2;
  bool isExpand = false;
  int noArrowMaxLines = 2;

  @override
  void initState() {
    super.initState();
    minLines = 2; // 解决有overflowWidget 隐藏与展开问题
    maxLines = minLines;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        children: [
          _titleView("带展开收缩Demo"),
          Container(
            alignment: Alignment.topLeft,
            margin: const EdgeInsets.all(20),
            child: ExtendedWrap(
              maxLines: maxLines,
              minLines: minLines,
              runSpacing: 12,
              spacing: 12,
              alignment: WrapAlignment.start,
              children: resultList.map((e) => _itemView(e)).toList(),
              overflowWidget: _expandButton(),
            ),
          ),
          _titleView("不带展开收缩Demo"),
          Container(
            alignment: Alignment.topLeft,
            margin: const EdgeInsets.all(20),
            child: ExtendedWrap(
              maxLines: noArrowMaxLines,
              runSpacing: 12,
              spacing: 12,
              alignment: WrapAlignment.start,
              children: resultList.map((e) => _itemView(e)).toList(),
            ),
          ),
          _buildButton(1),
          _buildButton(2),
          _buildButton(3),
          _buildButton(-1),
        ],
      ),
    );
  }

  Widget _titleView(String text) {
    return Container(
      height: 40,
      padding: EdgeInsets.only(left: 30),
      color: Color(0xffffefe9),
      alignment: Alignment.centerLeft,
      child: Text(text,
          style: TextStyle(
              color: Colors.red, fontWeight: FontWeight.bold, fontSize: 16)),
    );
  }

  Widget _itemView(String text) {
    return GestureDetector(
      onTap: () {
        print("$text is clicked...");
      },
      child: Container(
        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
        height: 30,
        decoration: BoxDecoration(
            color: Color(0xfff1f2f4),
            borderRadius: BorderRadius.all(Radius.circular(3))),
        child: Text(text,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 14, color: Color(0xff505051))),
      ),
    );
  }

  Widget _expandButton() {
    return GestureDetector(
      onTap: () {
        setState(() {
          isExpand = !isExpand;
          maxLines = isExpand ? 8 : minLines;
        });
      },
      child: Container(
        height: 30,
        width: 30,
        decoration: BoxDecoration(
            color: Color(0xfff1f2f4),
            borderRadius: BorderRadius.all(Radius.circular(15))),
        child: Icon(
          isExpand ? Icons.arrow_upward : Icons.arrow_downward,
          size: 24,
        ),
      ),
    );
  }

  Widget _buildButton(int limit) {
    String showTips;
    if (limit == -1) {
      limit = math.pow(2, 30).toInt();
      showTips = "显示全部";
    } else {
      showTips = "行数限制:$limit行";
    }
    return TextButton(
        onPressed: () {
          setState(() {
            noArrowMaxLines = limit;
          });
        },
        child: Text(showTips),
        style: ButtonStyle(
            padding: MaterialStateProperty.all(
                EdgeInsets.symmetric(vertical: 10, horizontal: 20)),
            backgroundColor: MaterialStateProperty.all(Color(0xfff1f2f4))));
  }
}

此示例演示了两种不同的ExtendedWrap用法:一种是可以展开和收缩的(通过点击按钮切换),另一种是固定行数且没有展开功能的。希望这对您有所帮助!


更多关于Flutter列表项自动换行插件extended_wrap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter列表项自动换行插件extended_wrap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用 extended_wrap 插件来实现 Flutter 列表项自动换行的代码示例。extended_wrap 插件允许你在列表项超过指定宽度时自动换行,非常适合在需要动态布局的场景中使用。

首先,你需要在 pubspec.yaml 文件中添加 extended_wrap 依赖:

dependencies:
  flutter:
    sdk: flutter
  extended_wrap: ^0.10.0  # 请确保使用最新版本,版本号可能会有所不同

然后运行 flutter pub get 来安装依赖。

接下来,在你的 Dart 文件中使用 ExtendedWrap 组件。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:extended_wrap/extended_wrap.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Extended Wrap Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Extended Wrap Example'),
        ),
        body: Center(
          child: Container(
            width: 300, // 你可以根据需要调整宽度
            child: ExtendedWrap(
              spacing: 8.0, // 列表项之间的间距
              runSpacing: 8.0, // 行之间的间距
              alignment: WrapAlignment.start, // 对齐方式
              crossAxisAlignment: WrapCrossAlignment.start, // 交叉轴对齐方式
              children: List.generate(
                20, // 生成20个列表项作为示例
                (index) => Chip(
                  label: Text('Item $index'),
                  backgroundColor: Colors.grey[300]!,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的 Flutter 应用,其中包含一个 ExtendedWrap 组件。ExtendedWrap 组件的 children 属性接受一个列表项(Widget)的列表。我们使用 List.generate 方法生成了20个 Chip 组件作为示例列表项。

ExtendedWrap 的参数说明:

  • spacing:列表项之间的水平间距。
  • runSpacing:行之间的垂直间距。
  • alignment:列表项的对齐方式。
  • crossAxisAlignment:交叉轴上的对齐方式。

你可以根据需要调整这些参数以及列表项的内容和样式。这个插件非常适合用于标签云、动态列表布局等场景。

回到顶部