搜索插件、代码仓与 APP 分类

chips_input 封面
插件详情v0.1.0

chips_input

一个 Flutter 小部件,用于创建带有多个芯片的输入框,可以从建议中选择。

近 30 天下载
215
喜欢数
41
Pub 分数
70

安装插件

flutter pub add chips_input

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

ChipsInput 是一个 Flutter 小部件,允许用户通过交互式芯片输入多个值,并提供实时建议。它支持动态创建芯片、根据输入过滤建议,并可自定义样式。非常适合用于标签、选项选择或以简洁直观的界面输入项目列表。该小部件可无缝集成到表单和数据输入流程中,通过即时反馈和视觉清晰度提升用户体验。

适合场景

  • 标签系统
  • 多选输入
  • 表单数据输入
  • 可搜索的芯片选择
  • 用户偏好收集
  • 动态列表创建

主要特点

  • 实时建议过滤
  • 可自定义的芯片外观
  • 支持键盘导航
  • 与表单字段轻松集成
  • 防止重复芯片
  • 可配置的输入验证

适合对象

  • 表单构建器
  • 基于标签的界面
  • 用户偏好选择器
  • 数据录入包含多个值
  • 交互式搜索组件

使用建议

  • 有限的平台特定行为
  • 除了去重之外,没有内置验证
  • 需要手动处理芯片移除
  • 可能需要自定义样式以支持复杂主题
  • 未针对非常大的建议集合进行优化

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

chips_input

Flutter library for building input fields with InputChips as input options.

Pub Version GitHub Workflow Status

Usage

Import
import 'package:chips_input/chips_input.dart';
Example

ChipsInput

First create some sort of Class that holds the data. You could also use a simple String.

class AppProfile {
  final String name;
  final String email;
  final String imageUrl;

  const AppProfile(this.name, this.email, this.imageUrl);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is AppProfile &&
          runtimeType == other.runtimeType &&
          name == other.name;

  @override
  int get hashCode => name.hashCode;

  @override
  String toString() {
    return name;
  }
}

Initialize some data and implement the ChipsInput Widget to your liking.

const mockResults = <AppProfile>[
    AppProfile('John Doe', 'jdoe@flutter.io',
        'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
    AppProfile('Paul', 'paul@google.com',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Fred', 'fred@google.com',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Brian', 'brian@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('John', 'john@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Thomas', 'thomas@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Nelly', 'nelly@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Marie', 'marie@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Charlie', 'charlie@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Diana', 'diana@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Ernie', 'ernie@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
    AppProfile('Gina', 'fred@flutter.io',
        'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
];

ChipsInput(
    maxChips: 3, // remove, if you like infinity number of chips
    initialValue: [mockResults[1]],
    findSuggestions: (String query) {
        if (query.isNotEmpty) {
            var lowercaseQuery = query.toLowerCase();
            final results = mockResults.where((profile) {
            return profile.name
                    .toLowerCase()
                    .contains(query.toLowerCase()) ||
                profile.email
                    .toLowerCase()
                    .contains(query.toLowerCase());
            }).toList(growable: false)
            ..sort((a, b) => a.name
                .toLowerCase()
                .indexOf(lowercaseQuery)
                .compareTo(
                    b.name.toLowerCase().indexOf(lowercaseQuery)));
            return results;
        }
        return mockResults;
    },
    onChanged: (data) {
        print(data);
    },
    chipBuilder: (context, state, AppProfile profile) {
        return InputChip(
            key: ObjectKey(profile),
            label: Text(profile.name),
            avatar: CircleAvatar(
            backgroundImage: NetworkImage(profile.imageUrl),
            ),
            onDeleted: () => state.deleteChip(profile),
            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        );
    },
    suggestionBuilder: (context, AppProfile profile) {
        return ListTile(
            key: ObjectKey(profile),
            leading: CircleAvatar(
            backgroundImage: NetworkImage(profile.imageUrl),
            ),
            title: Text(profile.name),
            subtitle: Text(profile.email),
        );
    },
)

Instead of the suggestionBuilder you can also pass an optionsViewBuilder for more customization:

//...
optionsViewBuilder: (context, onSelected, options) {
    return Align(
        alignment: Alignment.topLeft,
        child: Material(
            elevation: 4.0,
            child: Container(
                height: 200.0,
                child: ListView.builder(
                    padding: EdgeInsets.all(8.0),
                    itemCount: options.length,
                    itemBuilder: (BuildContext context, int index) {
                        final option = options.elementAt(index);
                        return GestureDetector(
                            onTap: () {
                                onSelected(option);
                            },
                            child: ListTile(
                                key: ObjectKey(option),
                                leading: CircleAvatar(
                                    backgroundImage: NetworkImage(option.imageUrl),
                                ),
                                title: Text(option.name),
                                subtitle: Text(option.email),
                            ),
                        );
                    },
                ),
            ),
        ),
    );
},
//...

Credit

所属分类

源码仓库

使用此插件的项目

暂无相关数据。