Flutter: How to change focus to another widget when a certain key is pressed on physical keyboard
1,360
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(),
],
),
),
),
),
);
}
}
Author by
West
Updated on December 30, 2022Comments
-
West over 1 year
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 almost 3 yearsI've retested and it doesnt seem to be working. Focus is not being set
-
Ashok Kuvaraja almost 3 yearsOkay brother, I will check and revert back.
-
Ashok Kuvaraja almost 3 years@West, Can you please check the current code snippets?
-
West almost 3 yearsScreen 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? -
Ashok Kuvaraja almost 3 yearsYes I ensured. Please wrap
MaterialApp
widget to the parent ofScaffold
widget and check? -
West almost 3 yearsSure that makes it render again. But seems now none of the TextFields can be typed into
-
West almost 3 yearsThanks I've edited your answer so that it allows the TextFields to be edited. I'll accept it now:)
-
West almost 3 yearsI've heard about issues with checking
event.runtimeType
in production so I instead useif (event.toString().contains('RawKeyDownEvent') && event.toString().contains('Enter')) {}