前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 中使用Chip 小部件【Flutter专题30】

Flutter 中使用Chip 小部件【Flutter专题30】

作者头像
徐建国
发布2022-03-30 15:35:02
2.8K0
发布2022-03-30 15:35:02
举报
文章被收录于专栏:个人路线

作者:坚果 华为云享专家,InfoQ签约作者,阿里云专家博主,51CTO博客首席体验官,开源项目GVA成员之一,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

本文是关于 Flutter 中的 Chip 小部件。我们将大致了解小部件的基本原理,然后通过代码来实现它。事不宜迟,让我们开始吧。

概述

典型的chip是一个圆角的小盒子。它有一个文本标签,并以一种有意义且紧凑的方式显示信息。chip可以在同一区域同时显示多个交互元素。一些流行的chip用例是:

  • 发布标签(您可以在许多 WordPress ,VuePress,知乎,掘金,公众号或 GitHub等大型平台上看到它们)。
  • 可删除的内容列表(一系列电子邮件联系人、最喜欢的音乐类型列表等)。

img

在 Flutter 中,您可以使用以下构造函数来实现 Chip 小部件:

代码语言:javascript
复制
Chip({
  Key? key, 
  Widget? avatar, 
  required Widget label, 
  TextStyle? labelStyle, 
  EdgeInsetsGeometry? labelPadding, 
  Widget? deleteIcon, 
  VoidCallback? onDeleted, 
  Color? deleteIconColor, 
  bool useDeleteButtonTooltip = true, 
  String? deleteButtonTooltipMessage, 
  BorderSide? side, 
  OutlinedBorder? shape, 
  Clip clipBehavior = Clip.none, 
  FocusNode? focusNode, 
  bool autofocus = false, 
  Color? backgroundColor, 
  EdgeInsetsGeometry? padding, 
  VisualDensity? visualDensity, 
  MaterialTapTargetSize? materialTapTargetSize, 
  double? elevation, 
  Color? shadowColor
})

只有label属性是必需的,其他是可选的。一些常用的有:

  • avatar:在标签前显示一个图标或小图像。
  • backgroundColor : chip的背景颜色。
  • padding:chip内容周围的填充。
  • deleteIcon:让用户删除chip的小部件。
  • onDeleted:点击deleteIcon时调用的函数。

您可以在官方文档中找到有关其他属性的更多详细信息。但是,对于大多数应用程序,我们不需要超过一半。

简单示例

这个小例子向您展示了一种同时显示多个chip的简单使用的方法。我们将使用Wrap小部件作为chip列表的父级。当当前行的可用空间用完时,筹码会自动下行。由于Wrap 小部件的间距属性,我们还可以方便地设置chip之间的距离。

截屏:

image-20220125100331474

代码:

代码语言:javascript
复制
Scaffold(
      appBar: AppBar(
        title: const Text('大前端之旅'),
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 10),
        child: Wrap(
            // space between chips
            spacing: 10,
            // list of chips
            children: const [
              Chip(
                label: Text('Working'),
                avatar: Icon(
                  Icons.work,
                  color: Colors.red,
                ),
                backgroundColor: Colors.amberAccent,
                padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
              ),
              Chip(
                label: Text('Music'),
                avatar: Icon(Icons.headphones),
                backgroundColor: Colors.lightBlueAccent,
                padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
              ),
              Chip(
                label: Text('Gaming'),
                avatar: Icon(
                  Icons.gamepad,
                  color: Colors.white,
                ),
                backgroundColor: Colors.pinkAccent,
                padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
              ),
              Chip(
                label: Text('Cooking & Eating'),
                avatar: Icon(
                  Icons.restaurant,
                  color: Colors.pink,
                ),
                backgroundColor: Colors.greenAccent,
                padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
              )
            ]),
      ),
    );

在这个例子中,chip只呈现信息。在下一个示例中,chip是可交互的。

复杂示例:动态添加和移除筹码

应用预览

chip

我们要构建的应用程序包含一个浮动操作按钮。按下此按钮时,将显示一个对话框,让我们添加一个新chip。可以通过点击与其关联的删除图标来删除每个chip。

以下是应用程序的工作方式:

完整代码

main.dart中的最终代码和解释:

代码语言:javascript
复制
// main.dart
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: '大前端之旅',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: const HomePage(),
    );
  }
}

// Data model for a chip
class ChipData {
  // an id is useful when deleting chip
  final String id;
  final String name;
  ChipData({required this.id, required this.name});
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // list of chips
  final List<ChipData> _allChips = [];

  // Text controller (that will be used for the TextField shown in the dialog)
  final TextEditingController _textController = TextEditingController();
  // This function will be triggered when the floating actiong button gets pressed
  void _addNewChip() async {
    await showDialog(
        context: context,
        builder: (_) {
          return AlertDialog(
            title: const Text('添加'),
            content: TextField(
              controller: _textController,
            ),
            actions: [
              ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _allChips.add(ChipData(
                          id: DateTime.now().toString(),
                          name: _textController.text));
                    });

                    // reset the TextField
                    _textController.text = '';

                    // Close the dialog
                    Navigator.of(context).pop();
                  },
                  child: const Text('提交'))
            ],
          );
        });
  }

  // This function will be called when a delete icon associated with a chip is tapped
  void _deleteChip(String id) {
    setState(() {
      _allChips.removeWhere((element) => element.id == id);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('大前端之旅'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(15),
        child: Wrap(
          spacing: 10,
          children: _allChips
              .map((chip) => Chip(
                    key: ValueKey(chip.id),
                    label: Text(chip.name),
                    backgroundColor: Colors.amber.shade200,
                    padding:
                        const EdgeInsets.symmetric(vertical: 7, horizontal: 10),
                    deleteIconColor: Colors.red,
                    onDeleted: () => _deleteChip(chip.id),
                  ))
              .toList(),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _addNewChip,
        child: const Icon(Icons.add),
      ),
    );
  }
}

结论

我们已经探索了 Chip 小部件的许多方面,并经历了不止一个使用该小部件的示例。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大前端之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 简单示例
  • 复杂示例:动态添加和移除筹码
    • 应用预览
      • 完整代码
      • 结论
      相关产品与服务
      云开发 CloudBase
      云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档