Skip to content

Latest commit

 

History

History
293 lines (245 loc) · 11.8 KB

README-ZH.md

File metadata and controls

293 lines (245 loc) · 11.8 KB

extended_keyboard

pub package GitHub stars GitHub forks GitHub license GitHub issues flutter-candies

Language: English | 中文简体

用于快速创建自定义键盘的插件。

安装

运行 flutter pub add extended_keyboard, 或者直接手动添加 extended_keyboard 到 pubspec.yaml 中的 dependencies.

dependencies:
  extended_keyboard: ^latest_version

使用

SystemKeyboard

用于管理系统键盘的高度并提供处理键盘布局更改的功能。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemKeyboard().init();
  runApp(const MyApp());
}

KeyboardBuilder

如果我们想要关闭系统键盘,并且保持输入框的不丢失焦点,我们没法再使用 SystemChannels.textInput.invokeMethod<void>('TextInput.hide') 了. 相关问题 flutter/flutter#16863

下面的代码是一种变通方案

TextField(
  showCursor: true,
  readOnly: true,
)

KeyboardTypeBuilder

用于监听 KeyboardType 改变的组件,并且提供 CustomKeyboardController 来控制自定义键盘的开关。

   KeyboardTypeBuilder(
     builder: (
       BuildContext context,
       CustomKeyboardController controller,
     ) =>
         ToggleButton(
       builder: (bool active) => Icon(
         Icons.sentiment_very_satisfied,
         color: active ? Colors.orange : null,
       ),
       activeChanged: (bool active) {
         _keyboardPanelType = KeyboardPanelType.emoji;
         if (active) {
           controller.showCustomKeyboard();
           if (!_focusNode.hasFocus) {
             SchedulerBinding.instance
                 .addPostFrameCallback((Duration timeStamp) {
               _focusNode.requestFocus();
             });
           }
         } else {
           controller.showSystemKeyboard();
         }
       },
       active: controller.isCustom &&
           _keyboardPanelType == KeyboardPanelType.emoji,
     ),
   ),

CustomKeyboardController

用于通知 KeyboardType 改变,并且控制自定义键盘的开关。

  • KeyboardType : 当前键盘的类型
  • isCustom : 是否是自定义键盘
  • showCustomKeyboard : 打开自定义键盘
  • hideCustomKeyboard : 关闭自定义键盘
  • showSystemKeyboard : 打开系统键盘 (通过将 readOnly 设置成 false)
  • unfocus : 使输入框失去焦点, 并且关闭系统和自定义键盘

KeyboardBuilder

如果使用 Scaffold,请确保将 Scaffold.resizeToAvoidBottomInset 设置为 false

使用 KeyboardBuilder 小部件来封装包含输入字段的区域,允许在其 builder 回调中创建自定义键盘布局。builder 函数接收一个名为 systemKeyboardHeight 的参数,该参数表示最后显示的系统键盘的高度。此参数可用于为您的自定义键盘设置适当的高度,从而确保无缝且直观的用户体验。

parameter description default
builder 一个构建器函数,它根据系统键盘高度返回一个小部件。 required
bodyBuilder 一个带 readOnly 参数的组件回调 required
resizeToAvoidBottomInset Scaffold.resizeToAvoidBottomInset 作用一致 true
controller 自定义键盘控制器 null
  return Scaffold(
    resizeToAvoidBottomInset: false,
    appBar: AppBar(title: const Text('ChatDemo(KeyboardBuilder)')),
    body: SafeArea(
      bottom: true,
      child: KeyboardBuilder(
        resizeToAvoidBottomInset: true,
        builder: (BuildContext context, double? systemKeyboardHeight) {
          return Container();
        },
        bodyBuilder: (bool readOnly) => Column(children: <Widget>[
          Row(
            children: <Widget>[
              Expanded(
                child: TextField(
                  readOnly: readOnly, 
                  showCursor: true,
                  onTap: () {
                    _customKeyboardController.showSystemKeyboard();
                  },
                ),
              ),
              KeyboardTypeBuilder(
                builder: (
                  BuildContext context,
                  CustomKeyboardController controller,
                ) =>
                    ToggleButton(
                  builder: (bool active) => Icon(
                    Icons.sentiment_very_satisfied,
                    color: active ? Colors.orange : null,
                  ),
                  activeChanged: (bool active) {
                    _keyboardPanelType = KeyboardPanelType.emoji;
                    if (active) {
                      controller.showCustomKeyboard();
                      if (!_focusNode.hasFocus) {
                        SchedulerBinding.instance
                            .addPostFrameCallback((Duration timeStamp) {
                          _focusNode.requestFocus();
                        });
                      }
                    } else {
                      controller.showSystemKeyboard();
                    }
                  },
                  active: controller.isCustom &&
                      _keyboardPanelType == KeyboardPanelType.emoji,
                ),
              ),
            ],
          ),
        ]),
      ),
    ),
  );

img

Full Demo

TextInputScope

KeyboardBinding / KeyboardBindingMixin

你可以直接使用 KeyboardBinding ,或者将 KeyboardBindingMixin 混入到你的 WidgetsFlutterBinding 中。

Future<void> main() async {
  KeyboardBinding();
  await SystemKeyboard().init();
  runApp(const MyApp());
}

KeyboardConfiguration

这个配置包括键盘应该如何构建,它的动画持续时间,它的名字。

parameter description default
getKeyboardHeight 返回自定义键盘的高度 required
builder 包含输入框的主体 required
keyboardName 自定义键盘的名字 required
showDuration 自定义键盘打开的时间 const Duration(milliseconds: 200)
hideDuration 自定义键盘隐藏的时间 const Duration(milliseconds: 200)
resizeToAvoidBottomInset Scaffold.resizeToAvoidBottomInset 一样的意思. 如果它不设置,将和 TextInputScope.resizeToAvoidBottomInset 的值相同 null
  KeyboardConfiguration(
    getKeyboardHeight: (double? systemKeyboardHeight) =>
        systemKeyboardHeight ?? 346,
    builder: () {
      return Container();
    },
    keyboardName: 'custom_number1',
    resizeToAvoidBottomInset: true,
  ),

TextInputScope

如果使用 Scaffold,请确保将 Scaffold.resizeToAvoidBottomInset 设置为 false

parameter description default
body 包含输入框的主体 required
configurations 自定义键盘配置 required
keyboardHeight 默认的自定义键盘高度 346
resizeToAvoidBottomInset Scaffold.resizeToAvoidBottomInset 的意思一样. true
  late List<KeyboardConfiguration> _configurations;
  @override
  void initState() {
    super.initState();
    _configurations = <KeyboardConfiguration>[
      KeyboardConfiguration(
        getKeyboardHeight: (double? systemKeyboardHeight) =>
            systemKeyboardHeight ?? 346,
        builder: () {
          return Container();
        },
        keyboardName: 'custom_number',
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('TextInputDemo'),
      ),
      resizeToAvoidBottomInset: false,
      body: SafeArea(
        bottom: true,
        child: TextInputScope(
          body: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 5),
            child: Column(
              children: <Widget>[
                TextField(
                  keyboardType: _configurations[0].keyboardType,
                  controller: _controller,
                  decoration: InputDecoration(
                    hintText:
                        'The keyboardType is ${_configurations[0].keyboardType.name}',
                  ),
                ),
              ],
            ),
          ),
          configurations: _configurations,
        ),
      ),
    );
  }

img

Full Demo

extension

TextEditingController 的扩展方法

  • void insertText(String text) 在当前位置插入文本
  • void delete() 删除一个字符
  • TextEditingValue deleteText() 删除一个字符并且返回删除之后的值,可以根据自己的情况再处理
  • void performAction(TextInputAction action)TextInputClient.performAction 一样的作用