1

I'm developing a desktop app on Windows and am trying to move focus to a Textfield when the ENTER key is pressed on another textfield. I'm able to detect the key has been pressed using RawKeyboardListener but focus isnt changed to the new field. How can I get this working?

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late FocusNode _txtNode;

  @override
  void initState() {
    super.initState();
    _txtNode = FocusNode();
  }

  @override
  void dispose() {
    _txtNode.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Stack(
            children: [
              Container(
              height: 400,
              width: 500,
              color: Colors.grey[350],
              child: Column(
                children: [
                  Container(
                      height: 100,
                      child: RawKeyboardListener(
                        focusNode: FocusNode(),
                          onKey: (event){
                          if (event.toString().contains('RawKeyDownEvent') && event.toString().contains('Enter')) {
                            print("pressed ENTER");
                            _txtNode.requestFocus();
                          }
                          },
                          child: TextField(readOnly: true,))
                  ),
                  TextField(
                  ),
                  TextField(
                    focusNode: _txtNode,
                  ),
                ],
              ),
            ),
          ]
          ),
        ),
      ),
    );
  }
}
West
  • 2,350
  • 5
  • 31
  • 67

1 Answers1

2

I have achieved your use case by just modified your code snippets. Please check the below code snippets. FocusScope.of(context).nextFocus() is used to move the focus to the next. If you want to move a focus to a specific widget. you just call that focusNode.requestFocus().


class FocusDemo extends StatefulWidget {
  @override
  _FocusDemoState createState() => _FocusDemoState();
}

class _FocusDemoState extends State<FocusDemo> {
  late FocusNode _txtNode;

  @override
  void initState() {
    super.initState();
    _txtNode = FocusNode();
  }

  @override
  void dispose() {
    _txtNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Focus(
          focusNode: _txtNode,
          onKey: (focusNode, event) {
            if (event.runtimeType == RawKeyUpEvent &&
                event.logicalKey == LogicalKeyboardKey.enter) {
              focusNode.nextFocus();
              return KeyEventResult.handled;
            }
            return KeyEventResult.ignored;
          },
          child: Container(
            height: 400,
            width: 500,
            color: Colors.grey[350],
            child: Column(
              children: [
                TextField(),
                TextField(),
                TextField(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

West
  • 2,350
  • 5
  • 31
  • 67
Ashok Kuvaraja
  • 666
  • 3
  • 11
  • I've retested and it doesnt seem to be working. Focus is not being set – West Jun 25 '21 at 05:30
  • Okay brother, I will check and revert back. – Ashok Kuvaraja Jun 25 '21 at 05:36
  • @West, Can you please check the current code snippets? – Ashok Kuvaraja Jun 25 '21 at 06:06
  • Screen doesnt render no more I got an error `No MediaQuery widget ancestor found.The relevant error-causing widget was: FocusDemo file:///C:/Users/Public/Android/Projects/tests/lib/main.dart:5:10` Are you testing the code before posting and does it work on your end? – West Jun 25 '21 at 06:31
  • Yes I ensured. Please wrap `MaterialApp` widget to the parent of `Scaffold` widget and check? – Ashok Kuvaraja Jun 25 '21 at 06:35
  • Sure that makes it render again. But seems now none of the TextFields can be typed into – West Jun 25 '21 at 06:51
  • Thanks I've edited your answer so that it allows the TextFields to be edited. I'll accept it now:) – West Jun 25 '21 at 07:22
  • I've heard about issues with checking `event.runtimeType` in production so I instead use `if (event.toString().contains('RawKeyDownEvent') && event.toString().contains('Enter')) {}` – West Jun 25 '21 at 07:27