写点什么

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

作者:坚果
  • 2022 年 1 月 25 日
  • 本文字数:3455 字

    阅读完需:约 11 分钟

Flutter 中使用 Chip 小部件


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


作者:坚果

公众号:"大前端之旅"

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

概述

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


  • 发布标签(您可以在许多 WordPress ,VuePress,知乎,掘金,公众号或 GitHub 等大型平台上看到它们)。

  • 可删除的内容列表(一系列电子邮件联系人、最喜欢的音乐类型列表等)。



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


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 之间的距离。


截屏:



代码:


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。


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

完整代码

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


// main.dartimport '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 chipclass 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 小部件的许多方面,并经历了不止一个使用该小部件的示例。


大家喜欢的话,点赞支持一下坚果

发布于: 刚刚阅读数: 2
用户头像

坚果

关注

此间若无火炬,我便是唯一的光 2020.10.25 加入

公众号:“大前端之旅”,华为云享专家,InfoQ签约作者,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

评论

发布
暂无评论
Flutter 中使用Chip 小部件【Flutter专题66】