目录
  • 创建关键小部件
    • 文本键
    • Backspace键
  • 将按键组成键盘
    • 在应用程序中使用键盘
      • 处理文本输入
      • 处理退格
    • 防止系统键盘显示
      • 在系统键盘和自定义键盘之间切换
    • 完整代码

      本文将向您展示如何创建自定义键盘小部件,用于在您自己的应用程序中的Flutter TextField中输入文本。使用案例包括特殊字符或语言的文本输入,其中系统键盘可能不存在或用户可能没有安装正确的键盘。

      我们今天将制作一个更简单的版本:

      详解Flutter自定义应用程序内键盘的实现方法

      详解Flutter自定义应用程序内键盘的实现方法

      注意 :本文不会告诉您如何构建用户在任何应用程序中安装和使用的系统键盘。这只是一种基于小部件的方法,可以在您自己的应用程序中使用。

      完整的代码在文章的底部。

      创建关键小部件

      Flutter的优点是,通过组合更简单的小部件,可以轻松构建键盘等复杂布局。首先,您将创建几个简单的按键小部件。

      文本键

      我已经圈出了由您首先制作的TextKey小部件制作的键。

      详解Flutter自定义应用程序内键盘的实现方法

      显示文本键(包括空格键)的自定义写意红色圆圈

      将以下TextKey小部件添加到您的项目中:

      class TextKey extends StatelessWidget {
        const TextKey({
          Key key,
          @required this.text,
          this.onTextInput,
          this.flex = 1,
        }) : super(key: key);
        final String text;
        final ValueSetter<String> onTextInput;
        final int flex;
        @override
        Widget build(BuildContext context) {
          return Expanded(
            flex: flex,
            child: Padding(
              padding: const EdgeInsets.all(1.0),
              child: Material(
                color: Colors.blue.shade300,
                child: InkWell(
                  onTap: () {
                    onTextInput?.call(text);
                  },
                  child: Container(
                    child: Center(child: Text(text)),
                  ),
                ),
              ),
            ),
          );
        }
      }
      

      以下是有趣的部分:

      • flex属性允许您的按键均匀分布在一行之间,甚至占据行的更大比例(如上图中的空格键)。
      • 按下按键后,它将以anonTextInput回调的形式将其值传递给键盘。

      Backspace键

      您还需要一个与TextKey小部件具有不同外观和功能的退格键。

      详解Flutter自定义应用程序内键盘的实现方法

      退格键

      将以下小部件添加到您的项目中:

      ​
      class BackspaceKey extends StatelessWidget {
        const BackspaceKey({
          Key? key,
          this.onBackspace,
          this.flex = 1,
        }) : super(key: key);
      ​
        final VoidCallback? onBackspace;
        final int flex;
      ​
        @override
        Widget build(BuildContext context) {
          return Expanded(
            flex: flex,
            child: Padding(
              padding: const EdgeInsets.all(1.0),
              child: Material(
                color: Colors.blue.shade300,
                child: InkWell(
                  onTap: () {
                    onBackspace?.call();
                  },
                  child: Container(
                    child: Center(
                      child: Icon(Icons.backspace),
                    ),
                  ),
                ),
              ),
            ),
          );
        }
      

      备注:

      • TextKey代码有点重复,因此一些重构是为了使其更加简介。
      • onBackspaceVoidCallback,因为不需要将任何文本传递回键盘。

      将按键组成键盘

      一旦有了按键,键盘就很容易布局,因为它们只是列中的行。

      详解Flutter自定义应用程序内键盘的实现方法

      包含三行的列

      这是代码。我省略了一些重复的部分,以便简洁。不过,你可以在文章的末尾找到它。


      class CustomKeyboard extends StatelessWidget {
      CustomKeyboard({
      Key? key,
      this.onTextInput,
      this.onBackspace,
      }) : super(key: key);

      final ValueSetter<String>? onTextInput;
      final VoidCallback? onBackspace;

      void _textInputHandler(String text) => onTextInput?.call(text);

      void _backspaceHandler() => onBackspace?.call();

      @override
      Widget build(BuildContext context) {
      return Container(
      height: 160,
      color: Colors.blue,
      child: Column(
      children: [
      buildRowOne(),
      buildRowTwo(),
      buildRowThree(),
      buildRowFour(),
      buildRowFive()
      ],
      ),
      );
      }

      Expanded buildRowOne() {
      return Expanded(
      child: Row(
      children: [
      TextKey(
      text: '坚',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '果',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '祝',
      onTextInput: _textInputHandler,
      ),
      ],
      ),
      );
      }

      Expanded buildRowTwo() {
      return Expanded(
      child: Row(
      children: [
      TextKey(
      text: 'I',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: 'n',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: 'f',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: 'o',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: 'Q',
      onTextInput: _textInputHandler,
      ),
      ],
      ),
      );
      }

      Expanded buildRowThree() {
      return Expanded(
      child: Row(
      children: [
      TextKey(
      text: '十',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '五',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '周',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '年',
      onTextInput: _textInputHandler,
      ),
      ],
      ),
      );
      }

      Expanded buildRowFour() {
      return Expanded(
      child: Row(
      children: [
      TextKey(
      text: '生',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '日',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '快',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '乐',
      onTextInput: _textInputHandler,
      ),
      TextKey(
      text: '!',
      onTextInput: _textInputHandler,
      ),
      ],
      ),
      );
      }

      Expanded buildRowFive() {
      return Expanded(
      child: Row(
      children: [
      TextKey(
      text: '

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。