Flutter:使用textField读取条形码时隐藏键盘

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

我正在尝试使用文本字段来使用设备中的内置阅读器来读取条形码。 但是,我想在阅读时隐藏键盘。

我使用这个代码:


class InputWithKeyboardControl extends EditableText {
  /// startShowKeyboard is initial value to show or not the keyboard when the widget is created, default value is false
  final bool startShowKeyboard;

  /// focusNode is responsible for controlling the focus of the field, this parameter is required
  final InputWithKeyboardControlFocusNode focusNode;

  /// width is responsible for set the widget size, This parameter is required
  final double width;

  /// buttonColorEnabled is responsible for set color in button when is enabled, default value is Colors.blue
  final Color buttonColorEnabled;

  /// buttonColorDisabled is responsible for set color in button when is disabled, default value is Colors.black
  final Color buttonColorDisabled;

  /// underlineColor is responsible for set color in underline BorderSide, default value is Colors.black
  final Color underlineColor;

  /// showUnderline is responsible for showing or not the underline in the widget, default value is true
  final bool showUnderline;

  /// showButton is responsible for showing or not the button to control the keyboard, default value is true
  final bool showButton;

  InputWithKeyboardControl({
    required TextEditingController controller,
    TextStyle style = const TextStyle(color: Colors.black, fontSize: 18),
    Color cursorColor = Colors.black,
    bool autofocus = false,
    Color? selectionColor,
    this.startShowKeyboard = false,
    void Function(String)? onSubmitted,
    void Function(String)? onChanged,
    required this.focusNode,
    required this.width,
    this.buttonColorEnabled = Colors.blue,
    this.buttonColorDisabled = Colors.black,
    this.underlineColor = Colors.black,
    this.showUnderline = true,
    this.showButton = true,
  }) : super(
            //showCursor: false,
            controller: controller,
            focusNode: focusNode,
            showCursor: false,
            style: style,
            keyboardType: TextInputType.number,
            cursorColor: cursorColor,
            autofocus: autofocus,
            selectionColor: selectionColor,
            backgroundCursorColor: Colors.black,
            onSubmitted: onSubmitted,
            onChanged: onChanged);

  @override
  EditableTextState createState() {
    return InputWithKeyboardControlState(startShowKeyboard, focusNode, width, buttonColorEnabled, buttonColorDisabled,
        underlineColor, showUnderline, showButton);
  }
}

class InputWithKeyboardControlState extends EditableTextState {
  /// showKeyboard is initial value to show or not the keyboard when the widget is created, default value is false
  bool showKeyboard;

  /// focusNode is responsible for controlling the focus of the field, this parameter is required
  final InputWithKeyboardControlFocusNode focusNode;

  /// width is responsible for set the widget size, This parameter is required
  final double width;

  /// buttonColorEnabled is responsible for set color in button when is enabled, default value is Colors.blue
  final Color buttonColorEnabled;

  /// buttonColorDisabled is responsible for set color in button when is disabled, default value is Colors.black
  final Color buttonColorDisabled;

  /// underlineColor is responsible for set color in underline BorderSide, default value is Colors.black
  final Color underlineColor;

  /// showUnderline is responsible for showing or not the underline in the widget, default value is true
  final bool showUnderline;

  /// showButton is responsible for showing or not the button to control the keyboard, default value is true
  final bool showButton;

  // funcionListener is responsible for controller focusNode listener
  late Function funcionListener;

  @override
  void initState() {
    funcionListener = () {
      if (focusNode.hasFocus) requestKeyboard();
    };

    focusNode.addListener(funcionListener as void Function());
    super.initState();
  }

  @override
  Future didChangeAppLifecycleState(AppLifecycleState state) async {
    focusNode.requestFocus();
    SystemChannels.textInput.invokeMethod('TextInput.show');
    Future.delayed(Duration(microseconds: 0), () {
      SystemChannels.textInput.invokeMethod('TextInput.hide');
      focusNode.requestFocus();
    });
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    focusNode.removeListener(funcionListener as void Function());
    super.dispose();
  }

  InputWithKeyboardControlState(this.showKeyboard, this.focusNode, this.width, this.buttonColorEnabled,
      this.buttonColorDisabled, this.underlineColor, this.showUnderline, this.showButton);

  toggleShowKeyboard(bool value) {
    setState(() {
      showKeyboard = !value;
    });

    if (!showKeyboard) {
      Future.delayed(Duration(microseconds: 1), () {
        SystemChannels.textInput.invokeMethod('TextInput.hide');
        focusNode.requestFocus();
      });
    } else {
      SystemChannels.textInput.invokeMethod('TextInput.show');
      focusNode.requestFocus();
    }
  }

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;

    Widget widget = super.build(context);
    return Container(
      width: width,
      child: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Expanded(
              child: Container(
                  decoration: showUnderline
                      ? UnderlineTabIndicator(
                          borderSide: BorderSide(color: underlineColor),
                        )
                      : null,
                  child: widget),
            ),
            SizedBox(
              width: size.width * 0.01,
            ),
            showButton
                ? Container(
                    child: InkWell(
                      onTap: () {
                        this.toggleShowKeyboard(showKeyboard);
                      },
                      child: Container(
                        child: Icon(
                          color: const Color.fromRGBO(190, 190, 190, 1),
                          InvoIcons.keyboard_layout_float2,
                          //color: showKeyboard ? buttonColorEnabled : buttonColorDisabled,
                        ),
                      ),
                    ),
                  )
                : Container(),
          ],
        ),
      ),
    );
  }

  @override
  void requestKeyboard() {
    super.requestKeyboard();

    if (!showKeyboard) SystemChannels.textInput.invokeMethod('TextInput.hide');
  }
}

class InputWithKeyboardControlFocusNode extends FocusNode {
  @override
  bool consumeKeyboardToken() {
    return false;
  }
}

但打开页面时键盘仍会出现一秒钟。有什么办法可以隐藏吗

我尝试使用键盘监听器和条形码监听器,但收到此错误:

SPAN_EXCLUSIVE_EXCLUSIVE 跨度的长度不能为零

flutter keyboard textfield hide barcode
1个回答
0
投票

当您想隐藏它时,可以将

keyboardType
设置为
TextInputType.none
。当你想显示它时,将其设置为
TextInputType.number

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

class MyInput extends StatefulWidget {
  const MyInput({super.key});

  @override
  State<MyInput> createState() => _MyInputState();
}

class _MyInputState extends State<MyInput> {
  bool _showKeyboard = false;
  TextEditingController controller = TextEditingController();

  @override
  dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (_showKeyboard) {
      return Column(
        children: [
          TextField(
            key: Key('show'),
            keyboardType: TextInputType.number,
            autofocus: true,
            controller: controller,
          ),
          ElevatedButton(
            onPressed: () {
              setState(() {
                _showKeyboard = false;
                SystemChannels.textInput.invokeMethod('TextInput.hide');
              });
            },
            child: const Text('Hide Keyboard'),
          ),
        ],
      );
    } else {
      return Column(
        children: [
          TextField(
            key: Key('hide'),
            keyboardType: TextInputType.none,
            autofocus: true,
            controller: controller,
          ),
          ElevatedButton(
            onPressed: () {
              setState(() {
                _showKeyboard = true;
              });
              SystemChannels.textInput.invokeMethod('TextInput.show');
            },
            child: const Text('Show Keyboard'),
          ),
        ],
      );
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.