Flutter输入选择芯片插件choose_input_chips的使用

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

Flutter输入选择芯片插件choose_input_chips的使用

简介

choose_input_chips 是一个Flutter库,用于构建具有多个值的表单字段,并以输入芯片的形式展示这些值。它的外观类似于一个文本框,用户可以在其中输入文本以填充覆盖层中的建议项,供用户选择匹配的项目。该插件最初由Danvick Miller创建,名为flutter_chips_input,并在许多贡献者的帮助下进行了增强。

使用方法

安装

在你的pubspec.yaml文件中添加以下依赖项,然后运行flutter pub get

dependencies:
  choose_input_chips: ^1.1.3
导入

在你的Dart文件中导入choose_input_chips库:

import 'package:choose_input_chips/choose_input_chips.dart';
示例代码

以下是一个完整的示例代码,展示了如何使用choose_input_chips插件来创建一个带有输入芯片的表单字段。

import 'package:flutter/material.dart';
import 'package:choose_input_chips/choose_input_chips.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 MaterialApp(
      title: 'ChipsInput Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  [@override](/user/override)
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  final _chipKey = GlobalKey<ChipsInputState>();

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 模拟数据
    const mockResults = <AppProfile>[
      AppProfile('Charlie', 'charlie@flutter.io', 'man-1.png'),
      AppProfile('Diana', 'diana@flutter.io', 'woman-1.png'),
      AppProfile('Fred', 'fred@flutter.io', 'man-2.png'),
      AppProfile('Gina', 'gina@flutter.io', 'woman-2.png'),
      AppProfile('John', 'john@flutter.io', 'man-3.png'),
      AppProfile('Marie', 'marie@flutter.io', 'woman-3.png'),
      AppProfile('Pauline', 'pauline@flutter.io', 'woman-4.png'),
      AppProfile('Susan', 'susan@flutter.io', 'woman-5.png'),
      AppProfile('Thomas', 'thomas@flutter.io', 'man-4.png'),
    ];

    return Scaffold(
      appBar: AppBar(title: const Text('ChipsInput Example')),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text('Start typing a name below:'),
              ),
              // ChipsInput widget
              ChipsInput(
                key: _chipKey,
                initialValue: const [
                  AppProfile('John', 'john@flutter.io', 'man-3.png')
                ],
                allowChipEditing: true,
                textStyle: const TextStyle(
                  height: 1.5,
                  fontFamily: 'Roboto',
                  fontSize: 16,
                ),
                decoration: const InputDecoration(
                  labelText: 'Select People',
                ),
                findSuggestions: (String query) {
                  if (query.isNotEmpty) {
                    var lowercaseQuery = query.toLowerCase();
                    return 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 mockResults;
                },
                onChanged: (data) {
                  // this is a good place to update application state
                },
                chipBuilder: (context, state, dynamic profile) {
                  return InputChip(
                    key: ObjectKey(profile),
                    label: Text(profile.name),
                    avatar: CircleAvatar(
                      backgroundImage:
                          AssetImage('assets/avatars/${profile.imageName}'),
                    ),
                    onDeleted: () => state.deleteChip(profile),
                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                  );
                },
                suggestionBuilder: (context, state, dynamic profile) {
                  return ListTile(
                    key: ObjectKey(profile),
                    leading: CircleAvatar(
                      backgroundImage:
                          AssetImage('assets/avatars/${profile.imageName}'),
                    ),
                    title: Text(profile.name),
                    subtitle: Text(profile.email),
                    onTap: () => state.selectSuggestion(profile),
                  );
                },
              ),
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text('Click the button to add a specific chip'),
              ),
              ElevatedButton(
                onPressed: () {
                  _chipKey.currentState!.selectSuggestion(const AppProfile(
                      'Gina', 'gina@flutter.io', 'woman-3.png'));
                },
                child: const Text('Add Chip'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

// 定义AppProfile类
class AppProfile {
  final String name;
  final String email;
  final String imageName;

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

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

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

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

更多关于Flutter输入选择芯片插件choose_input_chips的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter输入选择芯片插件choose_input_chips的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用choose_input_chips插件的示例代码。这个插件允许用户通过输入文本并选择建议的芯片来输入多个选项。

首先,确保你已经在pubspec.yaml文件中添加了choose_input_chips依赖:

dependencies:
  flutter:
    sdk: flutter
  choose_input_chips: ^最新版本号  # 请替换为实际可用的最新版本号

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

接下来,下面是一个完整的示例代码,展示了如何在Flutter中使用choose_input_chips插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Choose Input Chips Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<String> suggestions = [
    'Apple',
    'Banana',
    'Cherry',
    'Date',
    'Elderberry',
    'Fig',
    'Grape',
    'Honeydew',
    'Indian Fig',
    'Jackfruit',
    // 可以添加更多建议项
  ];

  List<String> selectedChips = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Choose Input Chips Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              'Selected Chips:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 8),
            Wrap(
              children: selectedChips.map((chip) {
                return Chip(
                  label: Text(chip),
                  backgroundColor: Colors.blue.shade100,
                  onDelete: () {
                    setState(() {
                      selectedChips.remove(chip);
                    });
                  },
                );
              }).toList(),
            ),
            SizedBox(height: 24),
            ChooseInputChips<String>(
              suggestions: suggestions,
              onChanged: (chips) {
                setState(() {
                  selectedChips = chips;
                });
              },
              chipBuilder: (context, chipData) {
                return Chip(
                  label: Text(chipData),
                  backgroundColor: Colors.blue.shade100,
                  onDelete: () {
                    // 注意:这里的onDelete回调并不会直接移除chip,而是需要通过onChanged回调更新状态
                  },
                );
              },
              textStyle: TextStyle(fontSize: 16),
              decoration: InputDecoration(
                labelText: 'Select Fruits',
                border: OutlineInputBorder(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. suggestions列表包含了可供选择的建议项。
  2. selectedChips列表存储了用户已经选择的芯片。
  3. ChooseInputChips小部件用于显示输入字段和芯片选择列表。
  4. 当用户选择芯片时,onChanged回调会被触发,并更新selectedChips列表。
  5. 已选择的芯片会显示在ChooseInputChips小部件上方,并且每个芯片都有一个删除按钮。

注意,onDelete回调在Chip中并不会直接移除芯片,而是需要通过onChanged回调来更新状态。这是因为ChooseInputChips小部件内部维护了自己的状态,你需要通过回调来同步你的应用状态。

回到顶部