Flutter多标签选择器插件multi_tag_picker的使用

Flutter多标签选择器插件multi_tag_picker的使用

简介

multi_tag_picker 是一个结合了 flutter_typeahead 的文本字段与芯片(chip)行的 Flutter 库。它允许用户从建议列表中选择标签,并且可以创建新值。这与 choose_input_chips 类似,但此小部件提供了创建新值的功能。


安装

在项目的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  multi_tag_picker: ^1.0.0

然后运行以下命令以获取依赖项:

flutter pub get

导入

在需要使用的地方导入该库:

import 'package:multi_tag_picker/multi_tag_picker.dart';

示例代码

以下是一个完整的示例代码,展示了如何使用 multi_tag_picker 插件。

示例代码

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_syntax_view/flutter_syntax_view.dart';
import 'package:multi_tag_picker/multi_tag_picker.dart';

void main() => runApp(const MyApp());

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'MultiPicker Demo',
      home: MyHomePage(),
    );
  }
}

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

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _selectedValuesJson = '尚未找到任何标签...';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('MultiPicker 示例'),
      ),
      body: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: MultiTagPicker(
              textFieldConfiguration: const TextFieldConfiguration(
                decoration: InputDecoration(
                  border: InputBorder.none,
                  filled: true,
                  hintText: '输入查询',
                  labelText: '选择标签',
                ),
              ),
              findSuggestions: getLanguages,
              additionCallback: (value) {
                return Language(
                  name: value,
                  position: 0,
                );
              },
              configureSuggestion: (lang) {
                return SuggestionConfiguration(
                  title: Text(lang.name),
                  subtitle: Text(lang.position.toString()),
                  additionWidget: const Chip(
                    avatar: Icon(
                      Icons.add_circle,
                    ),
                    label: Text('添加新标签'),
                  ),
                );
              },
              placeholderItem: const Language(
                name: '占位符',
                position: 0,
              ),
              configureChip: (lang) {
                return ChipConfiguration(
                  label: Text(lang.name),
                );
              },
              onChanged: (values) {
                setState(() {
                  if (values.isEmpty) {
                    _selectedValuesJson = '已移除所有标签...';
                  } else {
                    _selectedValuesJson = values
                        .map<String>((lang) => '\n${lang.toJson()}')
                        .toList()
                        .toString()
                        .replaceFirst('}]', '}\n]');
                  }
                });
              },
            ),
          ),
          const Text(
            '已选择的标签',
            style: TextStyle(fontSize: 18.0),
          ),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                decoration: BoxDecoration(
                  border: Border.all(width: 1.0),
                ),
                child: SyntaxView(
                  code: _selectedValuesJson,
                  syntax: Syntax.JAVASCRIPT,
                  fontSize: 16.0,
                  expanded: true,
                  withLinesCount: false,
                  syntaxTheme: SyntaxTheme.standard(),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

/// 模拟从网络API获取语言数据,延迟500毫秒。
Future<List<Language>> getLanguages(String query) async {
  if (query.isEmpty) {
    return const [];
  }
  await Future.delayed(const Duration(milliseconds: 500), null);
  final lowercaseQuery = query.toLowerCase();
  return const [
    Language(name: 'Rust', position: 1),
    Language(name: 'Dart', position: 2),
    Language(name: 'Scheme', position: 3),
    Language(name: 'Swift', position: 4),
    Language(name: 'Erlang', position: 5),
    Language(name: 'Go', position: 6),
    Language(name: 'F#', position: 7),
    Language(name: 'Java', position: 8),
    Language(name: 'C#', position: 9),
    Language(name: 'JavaScript', position: 10),
    Language(name: 'APL', position: 11),
    Language(name: 'Python', position: 12),
    Language(name: 'Haxe', position: 13),
    Language(name: 'Io', position: 14),
    Language(name: 'Lua', position: 15),
    Language(name: 'OCaml', position: 16),
    Language(name: 'C++', position: 17),
    Language(name: 'Prolog', position: 18),
    Language(name: 'TypeScript', position: 19),
    Language(name: 'Zig', position: 20),
  ]
      .where((lang) => lang.name.toLowerCase().contains(lowercaseQuery))
      .toList(growable: false)
    ..sort((a, b) =>
        a.name.toLowerCase().indexOf(lowercaseQuery).compareTo(
            b.name.toLowerCase().indexOf(lowercaseQuery)));
}

/// Language 表示一种编程语言。
///
/// 此类重写了 `==` 运算符和 `hashCode` 方法,以便与其他相同类型的值进行合理的比较。
class Language {
  final String name;
  final int position;

  const Language({
    required this.name,
    required this.position,
  });

  [@override](/user/override)
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Language &&
          runtimeType == other.runtimeType &&
          name == other.name;

  [@override](/user/override)
  int get hashCode => name.hashCode;

  [@override](/user/override)
  String toString() {
    return name;
  }

  String toJson() => '''
  {
    "name": $name,
    "position": $position
  }''';
}

更多关于Flutter多标签选择器插件multi_tag_picker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter多标签选择器插件multi_tag_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


multi_tag_picker 是一个用于 Flutter 的多标签选择器插件,允许用户从一组标签中选择多个标签。它通常用于需要用户选择多个选项的场景,比如标签选择、兴趣选择等。

安装插件

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

dependencies:
  flutter:
    sdk: flutter
  multi_tag_picker: ^1.0.0  # 请检查最新版本

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

基本用法

以下是一个简单的使用示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Multi Tag Picker Example'),
        ),
        body: Center(
          child: MultiTagPickerExample(),
        ),
      ),
    );
  }
}

class MultiTagPickerExample extends StatefulWidget {
  @override
  _MultiTagPickerExampleState createState() => _MultiTagPickerExampleState();
}

class _MultiTagPickerExampleState extends State<MultiTagPickerExample> {
  List<String> selectedTags = [];

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        MultiTagPicker(
          tags: ['Flutter', 'Dart', 'Android', 'iOS', 'Web', 'Desktop'],
          initialTags: selectedTags,
          onChanged: (List<String> tags) {
            setState(() {
              selectedTags = tags;
            });
          },
        ),
        SizedBox(height: 20),
        Text('Selected Tags: ${selectedTags.join(', ')}'),
      ],
    );
  }
}

参数说明

  • tags: 这是一个字符串列表,表示所有可选的标签。
  • initialTags: 这是一个字符串列表,表示初始选中的标签。
  • onChanged: 这是一个回调函数,当用户选择或取消选择标签时调用。返回当前选中的标签列表。

自定义样式

multi_tag_picker 允许你通过 tagBuilderselectedTagBuilder 自定义标签的样式。

MultiTagPicker(
  tags: ['Flutter', 'Dart', 'Android', 'iOS', 'Web', 'Desktop'],
  initialTags: selectedTags,
  onChanged: (List<String> tags) {
    setState(() {
      selectedTags = tags;
    });
  },
  tagBuilder: (BuildContext context, String tag, bool isSelected) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      margin: EdgeInsets.all(4),
      decoration: BoxDecoration(
        color: isSelected ? Colors.blue : Colors.grey[300],
        borderRadius: BorderRadius.circular(20),
      ),
      child: Text(
        tag,
        style: TextStyle(
          color: isSelected ? Colors.white : Colors.black,
        ),
      ),
    );
  },
)

其他功能

multi_tag_picker 还支持其他一些功能,比如:

  • 标签搜索:可以通过 searchable 参数启用标签搜索功能。
  • 标签限制:可以通过 maxTags 参数限制用户最多可以选择多少个标签。
MultiTagPicker(
  tags: ['Flutter', 'Dart', 'Android', 'iOS', 'Web', 'Desktop'],
  initialTags: selectedTags,
  onChanged: (List<String> tags) {
    setState(() {
      selectedTags = tags;
    });
  },
  searchable: true,  // 启用搜索功能
  maxTags: 3,  // 最多选择3个标签
)
回到顶部