自定义十六进制键盘颤振

时间:2020-02-20 20:19:21

标签: flutter flutter-layout

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

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

有没有一种方法可以创建一个自定义键盘,看起来像仅由 0-9 AF 组成的android键盘?

1 个答案:

答案 0 :(得分: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,
                    ),
                  ),
          ),
        ),
      ),
    );
  }
}
相关问题