패키지, 저장소 및 앱 카테고리 검색

emoji_keyboard_flutter 표지
패키지 상세v1.7.5

emoji_keyboard_flutter

이모티콘만으로 입력할 수 있는 키보드를 제공하는 플러터 패키지!

AndroidiOS
30일 다운로드
240
좋아요
32
Pub 점수
140

패키지 설치

flutter pub add emoji_keyboard_flutter

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

이모지 입력 전용 키보드를 구현하는 플러터 패키지입니다. 표준 입력 방식을 사용자 정의 인터페이스로 대체하여 사용자가 이모지만 선택하고 입력할 수 있도록 하여, 재미있거나 표현력 있는 커뮤니케이션에 이상적입니다. 가볍고 안드로이드 및 iOS의 플러터 앱에 원활하게 통합됩니다. 소셜 앱이나 창의적인 메시징 플랫폼과 같이 이모지 중심 상호작용이 사용자 경험을 향상시키는 맥락에서 특히 유용합니다.

사용 사례

  • 이모지 중심 메시징 앱
  • 재미있는 사용자 인터페이스
  • 창의적 콘텐츠 생성 도구
  • 소셜 미디어 통합
  • 인터랙티브 채팅 기능

주요 기능

  • 전용 이모지 입력
  • 크로스 플랫폼 지원 (Android 및 iOS)
  • 경량이며 간편한 통합
  • 사용자 정의 이모지 그리드
  • 무결점 플러터 통합

적합한 대상

  • 재미있거나 표현력 있는 앱을 개발하는 개발자
  • 어린 연령층을 대상으로 하는 앱
  • 메시징 또는 소셜 플랫폼
  • 이모지 중심 디자인을 활용한 UI 실험

고려 사항

  • 전통적인 텍스트 입력에 적합하지 않습니다
  • 이모지 전용 워크플로우에 한정
  • 사용자에게 추가적인 UX 안내가 필요할 수 있습니다
  • 플랫폼 키보드 처리 동작에 따라 다릅니다

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Flutter Emoji Keyboard

pub package

A Flutter package that provides a keyboard where you can only type with emojis!

It's a keyboard the way you expect it and more! But with less letters and only emojis.

Emoji selection Skin selection Search option
Emoji selection Skin selection Search option
Emoji popup widget Recent emojis Dark or Light mode
Emoji selection Skin selection Search option

Key features

Smooth and intuitive keyboard layout with all the emojis up to unicode 16.0 available in separate 8 categories with a 'recent chosen' tab.

You can easily switch between categories by swiping or selecting the category from the top bar.

Emojis that cannot be displayed are filtered out (only for Android)

You can even search for your emoji by using the search functionality available in the bottom bar.

From this keyboard you can also delete an emoji from the position of the cursor or add a space from the bottom bar.

Determine the height of the keyboard and show or hide it using a simple variable

The emojis have an indicator which shows if you can add a skin component to them. If this is the case you can add one by long pressing the emoji and selecting a skin component from the resulting popup window.

Change the default light setting to dark mode

Instead of the keyboard you can also use the quick emoji popup widget. Select one of the many quick reaction emojis or from your recent emojis. The widget has a "+" button that you can implement to open the regular emoji keyboard.

Usage

To use this plugin, add emoji_keyboard_flutter as dependency in your pubspec.yaml file.

Full Sample Usage

import 'dart:io';
import 'package:emoji_keyboard_flutter/emoji_keyboard_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Emoji Keyboard',
      home: MyHomePage(key: UniqueKey(), title: 'Emoji Keyboard'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({required Key key, required this.title}) : super(key: key);
  final String title;

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

class MyHomePageState extends State<MyHomePage> {
  bool showEmojiKeyboard = false;
  final TextEditingController controller = TextEditingController();
  int emojiReactionIndex = -1;
  bool showEmojiPopup = false;
  Offset emojiPopupPosition = Offset.zero;
  List<String> emojiReactions = ['', ''];
  bool darkMode = false;

  void backButtonFunctionality() {
    if (emojiReactionIndex != -1) {
      emojiReactionIndex = -1;
    }
    if (showEmojiPopup) {
      setState(() {
        showEmojiPopup = false;
      });
      return;
    }
    if (showEmojiKeyboard) {
      setState(() {
        showEmojiKeyboard = false;
      });
      return;
    }
    if (Platform.isAndroid) {
      SystemNavigator.pop();
    } else {
      exit(0);
    }
  }

  void onTapEmojiField() {
    emojiReactionIndex = -1;
    if (showEmojiPopup) {
      setState(() {
        showEmojiPopup = false;
      });
    }
    if (!showEmojiKeyboard) {
      setState(() {
        showEmojiKeyboard = true;
      });
    }
  }

  void onLongPressMessage(
      BuildContext context, LongPressStartDetails details, int messageIndex) {
    emojiReactionIndex = messageIndex;
    setState(() {
      showEmojiPopup = true;
      emojiPopupPosition = details.globalPosition;
    });
  }

  void handleEmojiPopupAction(EmojiPopupAction action) {
    showEmojiPopup = false;
    if (action is OutsideClicked) {
      emojiReactionIndex = -1;
    } else if (action is ButtonPressed) {
      showEmojiKeyboard = true;
    } else if (action is EmojiSelected) {
      final String newEmoji = action.emoji;
      if (emojiReactions[emojiReactionIndex] == newEmoji) {
        emojiReactions[emojiReactionIndex] = '';
      } else {
        emojiReactions[emojiReactionIndex] = action.emoji;
      }
      emojiReactionIndex = -1;
    }
    setState(() {});
  }

  void onActionEmojiChanged(String emoji) {
    if (emojiReactionIndex != -1) {
      emojiReactions[emojiReactionIndex] = emoji;
      emojiReactionIndex = -1;
      if (showEmojiKeyboard) {
        showEmojiKeyboard = false;
      }
      setState(() {});
    }
  }

  TextEditingController? getEmojiController() {
    if (emojiReactionIndex != -1) {
      return null;
    } else {
      return controller;
    }
  }

  Widget messageWidget(int messageIndex, String messageText) {
    return GestureDetector(
      onLongPressStart: (details) =>
          onLongPressMessage(context, details, messageIndex),
      child: Stack(
        children: [
          Container(
            width: MediaQuery.of(context).size.width,
            color: emojiReactionIndex == messageIndex
                ? Colors.cyan[200]
                : Colors.transparent,
            child: Container(
              margin: const EdgeInsets.all(8.0),
              padding: const EdgeInsets.all(12.0),
              decoration: BoxDecoration(
                color: messageIndex == 0 ? Colors.green[200] : Colors.blue[200],
                borderRadius: BorderRadius.only(
                  topLeft: messageIndex == 0
                      ? const Radius.circular(30.0)
                      : Radius.zero,
                  topRight: messageIndex == 1
                      ? const Radius.circular(30.0)
                      : Radius.zero,
                  bottomLeft: const Radius.circular(30.0),
                  bottomRight: const Radius.circular(30.0),
                ),
              ),
              child: Text(
                messageText,
                style: const TextStyle(fontSize: 16.0),
              ),
            ),
          ),
          if (emojiReactions[messageIndex] != '')
            Positioned(
              bottom: 0,
              right: 50,
              child: Container(
                padding: const EdgeInsets.all(4.0),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(12.0),
                ),
                child: Text(
                  emojiReactions[messageIndex],
                  style: const TextStyle(fontSize: 16.0),
                ),
              ),
            ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (bool didPop, result) {
        if (!didPop) {
          backButtonFunctionality();
        }
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Stack(
          children: [
            Column(
              children: [
                Expanded(
                  child: ListView(
                    reverse: true,
                    children: [
                      Container(
                        alignment: Alignment.topCenter,
                        padding: const EdgeInsets.only(
                            bottom: 12.0, left: 8, right: 8, top: 12),
                        child: TextFormField(
                          onTap: onTapEmojiField,
                          controller: controller,
                          decoration: const InputDecoration(
                              border: OutlineInputBorder()),
                          readOnly: true,
                          showCursor: true,
                        ),
                      ),
                      messageWidget(1,
                          'Or press the Textfield below to start typing with the emoji keyboard!'),
                      messageWidget(0,
                          'This is an example message. Long press to do an emoji reaction on this message!'),
                    ],
                  ),
                ),
                Align(
                  alignment: Alignment.bottomCenter,
                  child: EmojiKeyboard(
                    emojiController:
                        emojiReactionIndex == -1 ? controller : null,
                    onEmojiChanged: onActionEmojiChanged,
                    showEmojiKeyboard: showEmojiKeyboard,
                    emojiKeyboardHeight: 440, // optional defaults to 350
                    darkMode: darkMode, // optional defaults to false
                    emojiKeyboardAnimationDuration: const Duration(
                        milliseconds: 400), // optional defaults to null
                  ),
                ),
              ],
            ),
            EmojiKeyboardPopup(
              position: emojiPopupPosition,
              onAction: handleEmojiPopupAction,
              showEmojiPopup: showEmojiPopup,
              darkMode: darkMode, // optional defaults to false
              popupWidth: 350, // optional defaults to 350
              highlightedEmoji: emojiReactionIndex == -1
                  ? null
                  : emojiReactions[
                      emojiReactionIndex], // optional defaults to null
              emojiPopupAnimationDuration: const Duration(
                  milliseconds: 400), // optional defaults to null
            ),
          ],
        ),
      ),
    );
  }
}

See the example directory for the complete sample app.

카테고리

의존성

의존성 목록 3 개

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.