Flutter表情选择器插件emoji_picker_flutter_forked_for_web的使用

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

Flutter表情选择器插件emoji_picker_flutter_forked_for_web的使用

概述

emoji_picker_flutter_forked_for_web 是一个功能强大的 Flutter 表情选择器插件。它基于已弃用的 emoji_picker 插件重新开发,修复了原版的许多问题,并增加了现代化的功能。本插件支持 Material Design 和 Cupertino 风格,具有完全可定制性,并且能够过滤无法在设备上显示的表情符号(仅限 Android)。


关键特性

以下为插件的主要功能:

  • 轻量级包
  • 快速加载
  • 支持 Null 安全
  • 完全可自定义
  • 支持 Material Design 和 Cupertino 风格
  • 过滤无法显示的表情符号(仅限 Android)
  • 可选的最近使用表情符号标签
  • 支持皮肤色调

使用步骤

1. 添加依赖

首先,在项目的 pubspec.yaml 文件中添加插件依赖:

dependencies:
  emoji_picker_flutter_forked_for_web: ^最新版本号

然后运行 flutter pub get 更新依赖。


2. 基础使用示例

示例代码

以下是完整的使用示例代码:

import 'dart:io';
import 'package:emoji_picker_flutter_forked_for_web/emoji_picker_flutter.dart';
import 'package:flutter/foundation.dart' as foundation;
import 'package:flutter/material.dart';

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

/// 示例应用
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _controller = TextEditingController();
  bool emojiShowing = false;

  /// 当表情被选择时触发
  _onEmojiSelected(Emoji emoji) {
    _controller
      ..text += emoji.emoji
      ..selection = TextSelection.fromPosition(
          TextPosition(offset: _controller.text.length));
  }

  /// 当退格按钮被点击时触发
  _onBackspacePressed() {
    _controller
      ..text = _controller.text.characters.skipLast(1).toString()
      ..selection = TextSelection.fromPosition(
          TextPosition(offset: _controller.text.length));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          title: const Text('表情选择器示例'),
        ),
        body: Column(
          children: [
            // 输入框区域
            Expanded(
              child: Container(),
            ),
            Container(
              height: 66.0,
              color: Colors.blue,
              child: Row(
                children: [
                  // 打开表情选择器按钮
                  Material(
                    color: Colors.transparent,
                    child: IconButton(
                      onPressed: () {
                        setState(() {
                          emojiShowing = !emojiShowing;
                        });
                      },
                      icon: const Icon(
                        Icons.emoji_emotions,
                        color: Colors.white,
                      ),
                    ),
                  ),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      child: TextFormField(
                        controller: _controller,
                        style: const TextStyle(
                          fontSize: 20.0,
                          color: Colors.black87,
                          fontFamily: 'NotoColorEmoji',
                        ),
                        decoration: InputDecoration(
                          hintText: '输入消息',
                          filled: true,
                          fillColor: Colors.white,
                          contentPadding: const EdgeInsets.only(
                            left: 16.0,
                            bottom: 8.0,
                            top: 8.0,
                            right: 16.0,
                          ),
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(50.0),
                          ),
                        ),
                      ),
                    ),
                  ),
                  // 发送消息按钮
                  Material(
                    color: Colors.transparent,
                    child: IconButton(
                      onPressed: () {
                        // 发送消息逻辑
                      },
                      icon: const Icon(
                        Icons.send,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            // 表情选择器区域
            Offstage(
              offstage: !emojiShowing,
              child: SizedBox(
                height: 250,
                child: Builder(builder: (context) {
                  // 计算表情大小
                  final emojiSize =
                      48 * (!foundation.kIsWeb && Platform.isIOS ? 1.00 : 1.0);

                  // 计算每行表情数量
                  final columns =
                      MediaQuery.of(context).size.width ~/ emojiSize;

                  // 构建表情选择器
                  return EmojiPicker(
                    onEmojiSelected: (Category category, Emoji emoji) {
                      _onEmojiSelected(emoji);
                    },
                    onBackspacePressed: _onBackspacePressed,
                    config: Config(
                      columns: columns,
                      emojiSizeMax: emojiSize,
                      verticalSpacing: 8,
                      horizontalSpacing: 8,
                      initCategory: Category.RECENT,
                      bgColor: const Color(0xFFF2F2F2),
                      indicatorColor: Colors.blue,
                      iconColor: Colors.grey,
                      iconColorSelected: Colors.blue,
                      progressIndicatorColor: Colors.blue,
                      backspaceColor: Colors.blue,
                      // customEmojiFont: 'NotoColorEmoji',
                      skinToneDialogBgColor: Colors.white,
                      skinToneIndicatorColor: Colors.grey,
                      enableSkinTones: true,
                      showRecentsTab: true,
                      recentsLimit: 28,
                      noRecentsText: '无最近使用',
                      noRecentsStyle: const TextStyle(
                        fontSize: 20,
                        color: Colors.black26,
                      ),
                      tabIndicatorAnimDuration: kTabScrollDuration,
                      categoryIcons: const CategoryIcons(),
                      buttonMode: ButtonMode.MATERIAL,
                    ),
                  );
                }),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

3. 自定义视图

如果默认配置无法满足需求,可以通过继承 EmojiPickerBuilder 来进一步自定义视图。例如:

class CustomView extends EmojiPickerBuilder {
  CustomView(Config config, EmojiViewState state) : super(config, state);

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

class _CustomViewState extends State<CustomView> {
  @override
  Widget build(BuildContext context) {
    // 自定义表情选择器视图
    return Container(
      child: Text('自定义视图'),
    );
  }
}

EmojiPicker(
  onEmojiSelected: (category, emoji) { /* ... */ },
  config: Config(/* ... */),
  customWidget: (config, state) => CustomView(config, state),
)

4. Web 支持

自定义表情字体

某些平台可能无法正确显示所有表情符号。为了确保跨平台兼容性,可以添加自定义表情字体。

步骤 1: 在 pubspec.yaml 中添加字体
flutter:
  uses-material-design: true
  fonts:
    - family: NotoColorEmoji
      fonts:
        - asset: assets/fonts/NotoColorEmoji.ttf
步骤 2: 配置 EmojiPicker
EmojiPicker(
  config: Config(
    customEmojiFont: 'NotoColorEmoji',
    /* 其他配置 */
  ),
)

灵活调整每行表情数量

根据网页宽度动态调整表情数量:

final columns = MediaQuery.of(context).size.width ~/ emojiSize;

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

1 回复

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


emoji_picker_flutter_forked_for_web 是一个 Flutter 插件,用于在 Flutter 应用中集成表情选择器。它是 emoji_picker_flutter 的一个分支,专门为 Web 平台进行了优化和适配。以下是如何在 Flutter 项目中使用这个插件的步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  emoji_picker_flutter_forked_for_web: ^1.0.0

然后运行 flutter pub get 来获取依赖。

2. 导入包

在需要使用表情选择器的 Dart 文件中导入包:

import 'package:emoji_picker_flutter_forked_for_web/emoji_picker_flutter.dart';

3. 使用表情选择器

你可以通过 EmojiPicker 组件来显示表情选择器。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:emoji_picker_flutter_forked_for_web/emoji_picker_flutter.dart';

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

class _EmojiPickerExampleState extends State<EmojiPickerExample> {
  bool isEmojiVisible = false;
  TextEditingController _controller = TextEditingController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Emoji Picker Example'),
      ),
      body: Column(
        children: [
          Expanded(
            child: ListView(
              children: [
                TextField(
                  controller: _controller,
                  decoration: InputDecoration(
                    hintText: 'Type a message...',
                  ),
                ),
              ],
            ),
          ),
          Offstage(
            offstage: !isEmojiVisible,
            child: EmojiPicker(
              onEmojiSelected: (Category category, Emoji emoji) {
                _controller.text = _controller.text + emoji.emoji;
              },
              onBackspacePressed: () {
                // Handle backspace press
                _controller.text = _controller.text.substring(0, _controller.text.length - 1);
              },
              config: Config(
                columns: 7,
                emojiSizeMax: 32.0,
                verticalSpacing: 0,
                horizontalSpacing: 0,
                initCategory: Category.RECENT,
                bgColor: Color(0xFFF2F2F2),
                indicatorColor: Colors.blue,
                iconColor: Colors.grey,
                iconColorSelected: Colors.blue,
                progressIndicatorColor: Colors.blue,
                showRecentsTab: true,
                recentsLimit: 28,
                tabIndicatorAnimDuration: kTabScrollDuration,
                categoryIcons: const CategoryIcons(),
                buttonMode: ButtonMode.MATERIAL,
              ),
            ),
          ),
          Row(
            children: [
              IconButton(
                icon: Icon(Icons.emoji_emotions),
                onPressed: () {
                  setState(() {
                    isEmojiVisible = !isEmojiVisible;
                  });
                },
              ),
              Expanded(
                child: TextField(
                  controller: _controller,
                  decoration: InputDecoration(
                    hintText: 'Type a message...',
                  ),
                ),
              ),
              IconButton(
                icon: Icon(Icons.send),
                onPressed: () {
                  // Handle send message
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!