admin管理员组

文章数量:1122832

Im trying to have the return key act differently on my flutter web application depending on if the device has a physical keyboard (desktop/laptop) or a device with a virtual keyboard on the screen.

For physical keyboard devices I want return to perform a submit action and shift+return to create a new line. On virtual keyboard devices, return should create a new line. I cannot figure out a way to identify virtual keyboard key events. Heres my setup:

final FocusNode _focusNode = FocusNode();

@override
  void initState() {
    super.initState();
        _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        setState(() {
          isInputFocused = true;
        });
        ServicesBinding.instance.keyboard.addHandler(_handleKeyPress);
      } else {
        setState(() {
          isInputFocused = false;
        });
        ServicesBinding.instance.keyboard.removeHandler(_handleKeyPress);
      }
    });
 }

bool _handleKeyPress(KeyEvent event) {
    // Handle events that involve the return key
    if (event is KeyDownEvent && (event.physicalKey == PhysicalKeyboardKey.enter || event.logicalKey == LogicalKeyboardKey.enter)) {

      // Ignore virtual keyboard return keys. They should perform newline behavior
      if(event.logicalKey == LogicalKeyboardKey.enter) {
        return false; // Event handled
      }

      final shiftPressed = HardwareKeyboard.instance.isShiftPressed;

      if (shiftPressed) {
        // Handle Shift+Enter: Insert a newline
        final currentText = _controller.text;
        final selection = _controller.selection;
        final newText = currentText.replaceRange(
          selection.start,
          selection.end,
          '\n',
        );
        _controller.value = TextEditingValue(
          text: newText,
          selection: TextSelection.collapsed(
            offset: selection.start + 1,
          ),
        );
        return true; // Event handled
      } else {
        if(_controller.text.isNotEmpty) {
          // Handle Enter without shift
          _submitTextQuery();
          FocusManager.instance.primaryFocus?.unfocus();
          _controller.clear();
        }
        return true; // Event handled
      }
    }
    return false; // Let other events pass through
  }
@override
  Widget build(BuildContext context) {
...
TextFormField(
  autocorrect: true,
  spellCheckConfiguration: kIsWeb ? null : const SpellCheckConfiguration(),
  controller: widget.controller,
  focusNode: focusNode,
  maxLines: 5,
  minLines: 1,
  textCapitalization: TextCapitalization.sentences,
  inputFormatters: [LengthLimitingTextInputFormatter(500)],
  onChanged: (val) {
    setState(() {});
    widget.onChanged(val);
  },
  onTapOutside: (event) {
    widget.onTapOutside();
  },
  textInputAction: TextInputAction.newline,
  onSaved: (value) async {
    if (value == null || value.isEmpty == true) {
      return;
    }

    setState(() {
      widget.controller.clear();
    });
    FocusManager.instance.primaryFocus?.unfocus();
  },
  onFieldSubmitted: (value) async {
    if (value.isEmpty == true) {
      return;
    }
    widget.onSubmitQuery(value);
    setState(() {
      widget.controller.clear();
    });
    FocusManager.instance.primaryFocus?.unfocus();
  },
  onTap: () {
    setState(() {});
    widget.onTap();
  },
  style: AppTextStyles.light32,
)

本文标签: Flutter web handle keyboardreturn key depending on deviceStack Overflow