Custom Hex Keyboard Flutter

问题描述 投票:0回答:1

我在应用程序中使用TextField,并且在某个地方我希望用户仅输入Hexadecimal值。

我签出了[[TextField的keyboardType属性,但它无法执行我想要的操作。

是否有一种创建

自定义键盘

的方式,看起来像仅由0-9A-F组成的android键盘?
flutter flutter-layout
1个回答
1
投票
您可以在下面复制粘贴运行完整代码我建立了一个Hex键盘使用包https://pub.dev/packages/keyboard_actions基本上,它只修改官方https://github.com/diegoveloper/flutter_keyboard_actions/tree/master/example中的示例代码您可以使用以下代码段构建自定义按钮

children: [ _buildButton(text: "7"), _buildButton(text: "8"),

描述所有细节太长了。您可以直接在下面引用完整的代码

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart'; import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:intl/intl.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; final FocusNode _nodeText10 = FocusNode(); final custom3Notifier = ValueNotifier<String>(""); KeyboardActionsConfig _buildConfig(BuildContext context) { return KeyboardActionsConfig( keyboardActionsPlatform: KeyboardActionsPlatform.ALL, keyboardBarColor: Colors.grey[200], nextFocus: true, actions: [ KeyboardAction( focusNode: _nodeText10, displayActionBar: false, footerBuilder: (_) => HexKeyboard( focusNode: _nodeText10, notifier: custom3Notifier, ), ), ], ); } void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( children: <Widget>[ Expanded(child: Content()), ], ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } } class Content extends StatefulWidget { final bool isDialog; const Content({Key key, this.isDialog = false}) : super(key: key); @override _ContentState createState() => _ContentState(); } class _ContentState extends State<Content> { final FocusNode _nodeText10 = FocusNode(); final custom3Notifier = ValueNotifier<String>(""); /// Creates the [KeyboardActionsConfig] to hook up the fields /// and their focus nodes to our [FormKeyboardActions]. KeyboardActionsConfig _buildConfig(BuildContext context) { return KeyboardActionsConfig( keyboardActionsPlatform: KeyboardActionsPlatform.ALL, keyboardBarColor: Colors.grey[200], nextFocus: true, actions: [ KeyboardAction( focusNode: _nodeText10, displayActionBar: false, footerBuilder: (_) => HexKeyboard( focusNode: _nodeText10, notifier: custom3Notifier, ), ), ], ); } @override Widget build(BuildContext context) { return KeyboardActions( isDialog: widget.isDialog, config: _buildConfig(context), child: Container( padding: const EdgeInsets.all(15.0), child: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: <Widget>[ KeyboardCustomInput<String>( focusNode: _nodeText10, height: 65, notifier: custom3Notifier, builder: (context, val, hasFocus) { return Container( alignment: Alignment.center, child: Text( val.isEmpty ? "Tap Here" : val, style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500), ), ); }, ), ], ), ), ), ); } } class HexKeyboard extends StatelessWidget with KeyboardCustomPanelMixin<String> implements PreferredSizeWidget { final ValueNotifier<String> notifier; final FocusNode focusNode; HexKeyboard({ Key key, this.notifier, this.focusNode, }) : super(key: key); @override Size get preferredSize => Size.fromHeight(280); final format = NumberFormat("0000"); String _formatValue(String value) { final updatedValue = value; //format.format(double.parse(value)); /*final finalValue = updatedValue.substring(0, updatedValue.length - 2) + "." + updatedValue.substring(updatedValue.length - 2, updatedValue.length);*/ final finalValue = updatedValue; return finalValue; } void _onTapNumber(String value) { if (value == "Done") { focusNode.unfocus(); return; } final currentValue = notifier.value.replaceAll(".", ""); final temp = currentValue + value; updateValue(_formatValue(temp)); } void _onTapBackspace() { final currentValue = notifier.value.replaceAll(".", ""); final temp = currentValue.substring(0, currentValue.length - 1); updateValue(_formatValue(temp)); } @override Widget build(BuildContext context) { return Container( height: preferredSize.height, color: Color(0xFF313131), child: Padding( padding: const EdgeInsets.all(8.0), child: GridView( shrinkWrap: true, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, childAspectRatio: 2.2, crossAxisSpacing: 10, mainAxisSpacing: 10, ), children: [ _buildButton(text: "7"), _buildButton(text: "8"), _buildButton(text: "9"), _buildButton(text: "4"), _buildButton(text: "5"), _buildButton(text: "6"), _buildButton(text: "1"), _buildButton(text: "2"), _buildButton(text: "3"), _buildButton(text: "0"), _buildButton(text: "A"), _buildButton(text: "B"), _buildButton(text: "C"), _buildButton(text: "D"), _buildButton(text: "E"), _buildButton(text: "F"), _buildButton(icon: Icons.backspace, color: Colors.black), _buildButton(text: "Done", color: Colors.black), ], ), ), ); } Widget _buildButton({ String text, IconData icon, Color color, }) => NumericButton( text: text, icon: icon, color: color, onTap: () => icon != null ? _onTapBackspace() : _onTapNumber(text), ); } class NumericButton extends StatelessWidget { final String text; final VoidCallback onTap; final IconData icon; final Color color; const NumericButton({ Key key, this.text, this.onTap, this.icon, this.color, }) : super(key: key); @override Widget build(BuildContext context) { return Material( borderRadius: BorderRadius.circular(5.0), color: color ?? Color(0xFF4A4A4A), elevation: 5, child: InkWell( onTap: onTap, child: FittedBox( child: Padding( padding: const EdgeInsets.all(3.0), child: icon != null ? Icon( icon, color: Colors.white, ) : Text( text, style: TextStyle( color: Colors.white, fontWeight: FontWeight.w300, ), ), ), ), ), ); } }

© www.soinside.com 2019 - 2024. All rights reserved.