Flutter自定义键盘布局插件virtual_keyboard_custom_layout的使用

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

Flutter自定义键盘布局插件virtual_keyboard_custom_layout的使用

关于

virtual_keyboard_custom_layout 是一个为没有原生键盘的设备(如自助服务终端、ATM等)显示键盘的包。该库用Dart编写,不依赖任何原生代码。它分叉自 virtual_keyboard_multi_language

我选择从多语言版本中分叉出来,因为它更新得更频繁,并且有一些额外的自定义功能。

目标

这个依赖项非常适合我的项目,但其中一个小方面促使我分叉并发布了一个自定义版本。问题在于键盘布局缺乏足够的自定义性。我需要从两个初始预设中只保留几个键,并不能按照我想要的方式个性化它。因此,为了方便使用和自我提升,我创建了这个包,并对结果非常满意。

FlutterBlue FlutterBlue FlutterBlue

参考

VirtualKeyboard

Flutter小部件用于显示虚拟键盘。

  • 类型:可以是数字、字母数字或自定义。
    VirtualKeyboardType type
    
  • 按键事件回调:按下按键时调用,带有被按下的 Key 对象。
    Function onKeyPress;
    
  • 虚拟键盘高度:默认为300。
    double height;
    
  • 虚拟键盘宽度:默认为全屏宽度。
    double width;
    
  • 键文本和图标颜色
    Color textColor;
    
  • 键盘键字体大小
    double fontSize;
    
  • 仅大写字母启用
    bool alwaysCaps;
    
  • 多语言或单语言的自定义布局
    VirtualKeyboardLayoutKeys customLayoutKeys;
    
  • 用于多语言的默认布局:默认只有英语。
    List<VirtualKeyboardDefaultLayouts> defaultLayouts;
    
  • 反转布局以修复从右到左语言的问题
    bool reverseLayout;
    
  • 按键列表:所有都需要设置为字符串。
    bool keys;
    
  • 设置键盘所有键的边框颜色
    Color borderColor
    

VirtualKeyboardType

可用的虚拟键盘类型的枚举。

  • 仅数字
    VirtualKeyboardType.Numeric
    
  • 字母数字:字母 [A-Z] + 数字 [0-9] + @ + .
    VirtualKeyboardType.Alphanumeric
    
  • 自定义:所有类型+特殊键如 [“BACKSPACE”, “RETURN”, “SHIFT”, “SPACE” 和 “SWITCHLANGUAGE”]。
    VirtualKeyboardType.Custom
    

VirtualKeyboardKey

虚拟键盘键。

  • 键的文本
    String text
    
  • 大写的键文本
    String capsText;
    
  • 动作或字符串
    VirtualKeyboardKeyType keyType;
    
  • 键的动作
    VirtualKeyboardKeyAction action;
    

VirtualKeyboardKeyType

虚拟键盘键类型。

  • 可以是动作键 - Return, Backspace 等
    VirtualKeyboardKeyType.Action
    
  • 有文本值的键 - 字母、数字、逗号等
    VirtualKeyboardKeyType.String
    

VirtualKeyboardKeyAction

虚拟键盘动作。

enum VirtualKeyboardKeyAction { Backspace, Return, Shift, Space }

使用示例

显示自定义键盘

Container(
  color: Colors.grey,
  child: VirtualKeyboard(
    height: 350,
    width: 600,
    textColor: Colors.white,
    fontSize: 20,
    defaultLayouts: [VirtualKeyboardDefaultLayouts.English],
    type: VirtualKeyboardType.Custom,
    keys: const [
      ["T", "E", "S", "T"],
      ["C", "U", "S", "T", "O", "M"],
      ["L", "A", "Y", "O", "U", "T"],
      ["RETURN", "SHIFT", "BACKSPACE", "SPACE"],
    ],
    onKeyPress: _onKeyPress,
  ),
)

显示字母数字键盘

Container(
  color: Colors.deepPurple,
  child: VirtualKeyboard(
    height: 350,
    width: 600,
    textColor: Colors.white,
    fontSize: 20,
    defaultLayouts: [VirtualKeyboardDefaultLayouts.English],
    type: VirtualKeyboardType.Alphanumeric,
    onKeyPress: _onKeyPress,
  ),
)

显示数字键盘

Container(
  color: Colors.red,
  child: VirtualKeyboard(
    type: VirtualKeyboardType.Numeric,
    onKeyPress: (key) => print(key.text),
  ),
)

onKeyPressed事件基本用法示例

String text = '';
bool shiftEnabled = false;

_onKeyPress(VirtualKeyboardKey key) {
  if (key.keyType == VirtualKeyboardKeyType.String) {
    text = text + (shiftEnabled ? key.capsText : key.text);
  } else if (key.keyType == VirtualKeyboardKeyType.Action) {
    switch (key.action) {
      case VirtualKeyboardKeyAction.Backspace:
        if (text.length == 0) return;
        text = text.substring(0, text.length - 1);
        break;
      case VirtualKeyboardKeyAction.Return:
        text = text + '\n';
        break;
      case VirtualKeyboardKeyAction.Space:
        text = text + key.text;
        break;
      case VirtualKeyboardKeyAction.Shift:
        shiftEnabled = !shiftEnabled;
        break;
      default:
    }
  }
  setState(() {});
}

完整示例demo

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Virtual Keyboard Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Virtual Keyboard Demo'),
    );
  }
}

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

  @override
  // ignore: library_private_types_in_public_api
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String text = '';
  bool shiftEnabled = false;
  bool isNumericMode = false;
  TextEditingController controllerField01 = TextEditingController();
  TextEditingController controllerField02 = TextEditingController();
  TextEditingController controllerField03 = TextEditingController();
  var isKeyboardVisible = false;
  var controllerKeyboard = TextEditingController();
  late TypeLayout typeLayout;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        FocusScope.of(context).unfocus();
        setState(() {
          isKeyboardVisible = false;
        });
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              TextFormField(
                keyboardType: TextInputType.none,
                controller: controllerField01,
                onTap: () {
                  setState(() {
                    isKeyboardVisible = true;
                    controllerKeyboard = controllerField01;
                    typeLayout = TypeLayout.alphabet;
                  });
                },
              ),
              TextFormField(
                keyboardType: TextInputType.none,
                controller: controllerField02,
                onTap: () {
                  setState(() {
                    isKeyboardVisible = true;
                    controllerKeyboard = controllerField02;
                    typeLayout = TypeLayout.alphaEmail;
                  });
                },
              ),
              TextFormField(
                keyboardType: TextInputType.none,
                controller: controllerField03,
                onTap: () {
                  setState(() {
                    isKeyboardVisible = true;
                    controllerKeyboard = controllerField03;
                    typeLayout = TypeLayout.numeric;
                  });
                },
              ),
              Expanded(
                child: Container(),
              ),
              if (isKeyboardVisible)
                Stack(children: [
                  KeyboardAux(
                    alwaysCaps: true,
                    controller: controllerKeyboard,
                    typeLayout: typeLayout,
                    typeKeyboard: VirtualKeyboardType.Custom,
                  ),
                ]),
            ],
          ),
        ),
      ),
    );
  }
}

此完整示例展示了如何在不同场景下使用 virtual_keyboard_custom_layout 插件,包括显示自定义键盘、字母数字键盘和数字键盘,并处理按键事件。希望这对您有所帮助!


更多关于Flutter自定义键盘布局插件virtual_keyboard_custom_layout的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义键盘布局插件virtual_keyboard_custom_layout的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用virtual_keyboard_custom_layout插件来创建自定义键盘布局的示例代码。首先,你需要确保已经在pubspec.yaml文件中添加了该插件的依赖项:

dependencies:
  flutter:
    sdk: flutter
  virtual_keyboard_custom_layout: ^最新版本号  # 请替换为实际最新版本号

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

以下是一个完整的示例代码,展示了如何使用virtual_keyboard_custom_layout插件来创建一个简单的自定义键盘布局:

1. 创建自定义键盘布局

首先,你需要创建一个自定义键盘布局。这通常是在一个单独的Widget中完成的。

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

class CustomKeyboardLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CustomKeyboardButton(text: '1'),
            CustomKeyboardButton(text: '2'),
            CustomKeyboardButton(text: '3'),
          ],
        ),
        SizedBox(height: 10),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CustomKeyboardButton(text: '4'),
            CustomKeyboardButton(text: '5'),
            CustomKeyboardButton(text: '6'),
          ],
        ),
        SizedBox(height: 10),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CustomKeyboardButton(text: '7'),
            CustomKeyboardButton(text: '8'),
            CustomKeyboardButton(text: '9'),
          ],
        ),
        SizedBox(height: 10),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CustomKeyboardButton(text: '0'),
            CustomKeyboardButton(text: '删除', onPressed: () {
              // Handle backspace/delete action here
            }),
          ],
        ),
      ],
    );
  }
}

class CustomKeyboardButton extends StatelessWidget {
  final String text;
  final VoidCallback? onPressed;

  CustomKeyboardButton({required this.text, this.onPressed});

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: onPressed,
      style: TextButton.styleFrom(
        padding: EdgeInsets.all(16.0),
        primary: Colors.black,
        backgroundColor: Colors.white,
      ),
      child: Text(text),
    );
  }
}

2. 使用自定义键盘布局

接下来,在你的主应用程序中使用这个自定义键盘布局。你需要一个TextField来触发键盘的显示,并使用VirtualKeyboardController来管理键盘的显示和隐藏。

import 'package:flutter/material.dart';
import 'package:virtual_keyboard_custom_layout/virtual_keyboard_custom_layout.dart';
import 'custom_keyboard_layout.dart';  // 假设你将上面的代码保存在这个文件中

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Custom Keyboard Layout Example'),
        ),
        body: CustomKeyboardExample(),
      ),
    );
  }
}

class CustomKeyboardExample extends StatefulWidget {
  @override
  _CustomKeyboardExampleState createState() => _CustomKeyboardExampleState();
}

class _CustomKeyboardExampleState extends State<CustomKeyboardExample> {
  final VirtualKeyboardController _keyboardController =
      VirtualKeyboardController();
  TextEditingController _textController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        TextField(
          controller: _textController,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            labelText: 'Enter text',
          ),
          onEditingComplete: () {
            _keyboardController.hide();
          },
          onSubmitted: (value) {
            _keyboardController.hide();
          },
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () {
            _keyboardController.show(
              context: context,
              keyboardLayout: CustomKeyboardLayout(),
              onTextChanged: (text) {
                setState(() {
                  _textController.text += text;
                });
              },
              onDelete: () {
                if (_textController.text.isNotEmpty) {
                  setState(() {
                    _textController.text =
                        _textController.text.substring(0, _textController.text.length - 1);
                  });
                }
              },
            );
          },
          child: Text('Show Keyboard'),
        ),
      ],
    );
  }
}

注意事项

  1. 确保你已经正确安装了virtual_keyboard_custom_layout插件。
  2. 根据你的需求,你可能需要调整自定义键盘布局中的按钮和样式。
  3. 在实际使用中,你可能需要处理更多的键盘事件,比如换行、特殊字符等。

这个示例代码提供了一个基本的框架,你可以在此基础上进一步扩展和完善你的自定义键盘布局。

回到顶部