Flutter图标选择器插件flutter_iconpicker_flutter的使用

Flutter图标选择器插件flutter_iconpicker_flutter的使用

此包提供了一个图标选择器,支持(或自定义提供的)图标可以通过一个AlertDialog来选择。所有图标都与它们的名称在IconData中映射。这是必要的,以便可以通过名称搜索这些图标。全文本搜索包括如果没有找到结果的提示。

IconPicker

声明(重要)

此包定期维护,稳定且被许多软件解决方案用于生产环境(感谢你们所有人 🙏)。然而,不能保证所有图标都能正确显示。为什么?因为Flutter框架不断改变如Icons.camera这样的codePoint。因此,如果你开发的应用程序使用的是较旧的Flutter版本和flutter_iconpicker版本,那么你没有问题;但如果你想要更新你的应用程序和Flutter版本,codePoint可能会失效,并不再匹配如Icons.camera等图标。

所以我们可以做什么?

简单地通过提供一个包含正确codePointIconPickerIcon列表给IconPicker(而不是Icons.camera作为data参数!)

好的:'camera': IconData(0xe3af, fontFamily: 'MaterialIcons')

坏的:'camera': Icons.camera

例如,如果你想提供material图标,可以复制实际的图标文件,从这里:icons.dart,并将其提供给IconPicker作为自定义图标。

支持

图标包 支持
Material
Material Sharp
Material Rounded
Material Outlined
Cupertino
FontAwesome
LineAwesome

选择器模式

类型 支持
单个图标
多个图标

使用

要使用此包,在您的pubspec.yaml文件中添加flutter_iconpicker作为依赖项。

开始前的重要事项

图标包非常大,由您作为开发者按需生成以始终保持应用尽可能小!

要生成所需的图标包,只需执行以下命令:

dart run flutter_iconpicker:generate_packs --packs <material,cupertino,..>

<material,cupertino,..>替换为你需要的图标包名称!例如:--packs material,cupertino(逗号分隔)

更多参见:

dart run flutter_iconpicker:generate_packs --help

此Dart CLI程序生成你需要的所有图标包。

如果你打算更改图标包,你必须重新运行该命令!

为了简化,你可以设置该命令作为一个预脚本,在启动Flutter应用之前运行(如果你使用VSCode,请参阅:https://code.visualstudio.com/docs/editor/tasks)。这会自动化你的开发工作流程,对于构建发布应用,只需要在构建之前运行那个Dart脚本。

构建

如果你构建你的应用,它可能会因为这个包而失败。#TreeShakeIcons

为能够构建你的应用,添加到你的构建命令的标志:--no-tree-shake-icons,你应该就可以正常构建了!

更多参见:flutter/flutter#16311

API参考

参数 类型 默认值 简短描述
context(仅需) BuildContext - 由于AlertDialog的基础所需。
iconBuilder IconWidgetBuilder null 构建函数以创建每个图标的自定义Widget。警告:此构建器提供了你自己的逻辑来处理单选和多选拾取器中的onTap!因此,作为开发者,你负责处理onTap!此外,像showTooltips这样的参数在你创建自己的图标Widget时显然无效。
adaptiveDialog bool false 如果为true,IconPicker将根据屏幕大小进行适应。如果为false,IconPicker将在一个AlertDialog中显示自己。
barrierDismissible bool true 定义用户是否可以通过点击外部屏障来取消对话框。
iconSize double 40.0 定义可选的所有图标的大小。
iconColor Color Theme.of(context).iconTheme.color 设置所有可选图标的颜色。
mainAxisSpacing double 5.0 在主轴上放置多少空间来放置子项之间的间隔。
crossAxisSpacing double 5.0 在交叉轴上放置多少空间来放置子项之间的间隔。
iconPickerShape ShapeBorder RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)) 对话框的形状。
backgroundColor Color Theme.of(context).dialogBackgroundColor AlertDialog的背景色。
constraints BoxConstraints 如果adaptiveDialogtrue,则默认为:BoxConstraints(maxHeight: 500, minWidth: 450, maxWidth: 720),否则:BoxConstraints(maxHeight: 350, minWidth: 450, maxWidth: 678) 对话框的BoxConstraints,用于限制/设置:maxHeightmaxWidthminHeightminWidth
title Widget Text('Pick an icon') 拾取器的标题。位于[SearchBar]和[Icons]之上。
closeChild Widget Text('Close',textScaleFactor: 1.25,) 关闭默认对话框的AlertDialogFlatButton的内容。
searchIcon Icon Icon(Icons.search) 设置[SearchBar]中的前缀图标。
searchHintText String 'Search' 设置[SearchBar]中的TextFieldhintText
searchClearIcon Icon Icon(Icons.close) 设置[SearchBar]中的后缀图标。
searchComparator SearchComparator (String searchValue, IconPickerIcon icon) => icon.name.toLowerCase().contains(searchValue.toLowerCase()) 可以用来定义自定义搜索函数,应该返回一个[bool]。
noResultsText String 'No results for:' 当没有结果匹配搜索词时显示的文本。
showTooltips bool false 显示适当的标签在正确的图标下方。
showSearchBar bool true 如果为true,显示搜索栏在图标上方。
iconPackModes List<IconPack> const <IconPack>[IconPack.material] 要显示的图标模式。
customIconPack Map<String, IconPickerIcon> null 可以使用的自定义图标。
preSelected IconPickerIcon? null 打开图标选择器之前的预选图标。如果非空,则图标选择器突出显示并滚动到所选图标。
shouldScrollToSelectedIcon bool true 是否滚动到所选图标(对于较大的列表这可能有意义)或不滚动。
selectedIconBackgroundColor Color? Theme.of(context).brightness == Brightness.dark ? Colors.grey[800] : Colors.grey[400] [preSelected]的背景色。

自定义图标包

你可以通过传递一个包含图标名称和特定IconDataMap<String, IconPickerIcon>来提供你自己的图标包,并设置图标包模式:IconPack.custom

图标选择器的结果及进一步使用(保存和检索)

选择器返回一个IconPickerIcon,这是一个简单的类,例如:

IconPickerIcon(
    name: 'camera',
    data: Icons.camera, 
    pack: IconPack.material,
);
  • name:持有像camera这样的键名,即Icons.camera原始Material图标的名字。
  • data:持有用于显示图标的实际数据。例如:
  IconData(0xe3af, fontFamily: 'MaterialIcons');    // Icons.camera
  • pack:持有该图标属于哪个图标包的信息!这对于搜索和序列化目的非常重要。

如果你计划将选中的图标保存到任何地方(如sqflite,firebase等),你可以使用以下序列化方法:

  1. 调用此方法将选中的IconPickerIcon转换为一个Map:
serializeIcon(iconPickerIcon)
  1. 将已映射的图标检索回IconPickerIcon
deserializeIcon(map)

迁移指南:当更新到 >= 3.6.0 (重大变更)

现在,IconPicker支持IconPickerIcon? icon = await showIconPicker(...来选择一个图标,List<IconPickerIcon>? icons = await showMultipleIconPicker(...来一次选择多个图标。如果多个选择器因任何操作(屏障点击或关闭按钮)而被取消,结果将是所选图标。

你的单个或多个选择器的参数被移动到SinglePickerConfiguration用于showIconPickerMultiplePickerConfiguration用于showMultipleIconPicker。请使用这些configuration参数来设置你的选择器!更多参见下面的示例或查看示例文件夹。

在3.6.0之前
IconPickerIcon? icon = await showIconPicker(
  context,
  selectedIcon: Provider.of<IconNotifier>(context, listen: false).icon,
  adaptiveDialog: isAdaptive,
  showTooltips: showTooltips,
  showSearchBar: showSearch,
  iconPickerShape:
      RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
  iconPackModes: IconNotifier.starterPacks,
  searchComparator: (String search, IconPickerIcon icon) =>
      search
          .toLowerCase()
          .contains(icon.name.replaceAll('_', ' ').toLowerCase()) ||
      icon.name.toLowerCase().contains(search.toLowerCase()),
);
在3.6.0之后
IconPickerIcon? icon = await showIconPicker(
  context,
  configuration: SinglePickerConfiguration(
    preSelected: Provider.of<IconNotifier>(context, listen: false).icon,
    adaptiveDialog: isAdaptive,
    showTooltips: showTooltips,
    showSearchBar: showSearch,
    iconPickerShape:
        RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
    iconPackModes: IconNotifier.starterPacks,
    searchComparator: (String search, IconPickerIcon icon) =>
        search
            .toLowerCase()
            .contains(icon.name.replaceAll('_', ' ').toLowerCase()) ||
        icon.name.toLowerCase().contains(search.toLowerCase()),
  ),
);

迁移指南:当更新到 >= 3.3.1 (重大变更)

现在,IconPicker通过IconPickerIcon? icon = await showIconPicker(...调用,而不是像以前那样。请相应地更新你的代码!

注意:Material图标现在被分为:

  • 默认 -> 只有普通图标(不包括Sharp,Rounded,Outlined)
  • 全部 -> 所有的Material图标(包括Sharp,Rounded,Outlined)
  • Sharp -> 只有Sharp的Material图标
  • Rounded -> 只有Rounded的Material图标
  • Outlined -> 只有Outlined的Material图标

使用IconPack.allMaterial代替,如果你仍然想显示所有的Material图标。旧的枚举值是:IconPack.material

示例

如果你正在寻找一个带有DB存储的完整示例,请跳转到这里:ExampleProject

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

void main() {
  runApp(
    const MaterialApp(
      home: HomeScreen(),
    ),
  );
}

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

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

class _HomeScreenState extends State<HomeScreen> {
  Icon? _icon;

  _pickIcon() async {
    IconPickerIcon? icon = await showIconPicker(
        context,
        configuration: SinglePickerConfiguration(
          iconPackModes: [IconPack.cupertino],
        ),
    );

    _icon = Icon(icon.data);
    setState(() {});

    debugPrint('Picked Icon:  $icon');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _pickIcon,
              child: const Text('Open IconPicker'),
            ),
            const SizedBox(height: 10),
            AnimatedSwitcher(
              duration: const Duration(milliseconds: 300),
              child: _icon ?? Container(),
            ),
          ],
        ),
      ),
    );
  }
}

故障排除

问题:

This application cannot tree shake icons fonts. It has non-constant instances of IconData at the following locations:
  - file:///C:/Users/You/Development/FlutterIconPicker/lib/Serialization/iconDataSerialization.dart:127:16
Target web_release_bundle failed: Exception: Avoid non-constant invocations of IconData or try to build again with --no-tree-shake-icons.

解决方案:

在你的构建命令中添加:--no-tree-shake-icons


问题:

我的选中的图标包没有显示出来,当我设置iconPackModes: [...]

解决方案:

图标包非常大,由你作为开发者按需生成以始终保持应用尽可能小!

要生成你需要的图标包,只需执行以下命令:

dart run flutter_iconpicker:generate_packs --packs <material,cupertino,..>

<material,cupertino,..>替换为你需要的图标包名称!例如:--packs material,cupertino(逗号分隔)

更多参见:

dart run flutter_iconpicker:generate_packs --help

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

1 回复

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


flutter_iconpicker_flutter 是一个用于在 Flutter 应用中选择图标的插件。它提供了一个简单的界面,允许用户从一组预定义的图标中进行选择。以下是如何在 Flutter 项目中使用 flutter_iconpicker_flutter 插件的步骤。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 flutter_iconpicker_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_iconpicker_flutter: ^3.0.0  # 请检查最新版本

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

2. 导入包

在你的 Dart 文件中导入 flutter_iconpicker_flutter 包:

import 'package:flutter_iconpicker_flutter/flutter_iconpicker_flutter.dart';

3. 使用图标选择器

你可以使用 FlutterIconPicker.showIconPicker 方法来显示图标选择器,并获取用户选择的图标。

以下是一个简单的示例:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: IconPickerDemo(),
    );
  }
}

class IconPickerDemo extends StatefulWidget {
  [@override](/user/override)
  _IconPickerDemoState createState() => _IconPickerDemoState();
}

class _IconPickerDemoState extends State<IconPickerDemo> {
  IconData? _selectedIcon;

  Future<void> _pickIcon() async {
    IconData? icon = await FlutterIconPicker.showIconPicker(
      context,
      iconPackMode: IconPack.material, // 选择图标包
    );

    if (icon != null) {
      setState(() {
        _selectedIcon = icon;
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Icon Picker Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              _selectedIcon,
              size: 50.0,
              color: Colors.blue,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickIcon,
              child: Text('Pick an Icon'),
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部