Issue
I'd like to detect TextFormField with Focus(onFocusChange(bool))
, but when the TextFormField is in focus, the field isn't activated with the cursor as expected. I need to press tab again for the cursor to appear on the TextFormField. Any idea why the TextFormField doesn't get highlighted immediately on tab/next?
Form(
child: Column(
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
),
Focus(
onFocusChange: (bool inFocus){
/// When tab is pressed, I expect the cursor to be on TextFormField
debugPrint('TextFormField 2 in focus? $inFocus');
},
child: TextFormField(),
),
],
),
),
My current workaround on this issue is using a listener on FocusNode.
TextFormField(
focusNode: _focusNode,
),
But this requires initialization and proper disposal.
final _focusNodePrice = FocusNode();
@override
void initState() {
super.initState();
_focusNode.addListener(_onFocusChange);
}
@override
dispose(){
super.dispose();
_focusNode.removeListener(_onFocusChange);
_focusNode.dispose();
}
/// Handles the quirks of TextFormField requirements
void _onFocusChange() {
debugPrint('TextFormField inFocus? ${_focusNode.hasFocus}');
}
Here's a minimal repro of the issue.
import 'package:flutter/material.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, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FocusScope(
child: Form(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
decoration: InputDecoration(
hintText: 'Hint goes here 1'),
),
Focus(
onFocusChange: (bool inFocus){
debugPrint('TextFormField 2 in focus? $inFocus');
},
child: TextFormField(
textInputAction: TextInputAction.next,
decoration: InputDecoration(
hintText: 'Hint goes here 2'),
),
),
],
),
),
),
),
),
);
}
}
Solution
When you press tab or next the first time, the focus goes on the focus widget, then you press again and it goes on it's child, so you can just remove the focus widget
edit: if you need the Focus widget anyways, you can create a FocusNode and requestFocus as shown in your edited example below
import 'package:flutter/material.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, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
FocusNode node1 = FocusNode();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FocusScope(
child: Form(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
decoration: InputDecoration(hintText: 'Hint goes here 1'),
),
Focus(
onFocusChange: (bool inFocus) {
if (inFocus) FocusScope.of(context).requestFocus(node1);
debugPrint('TextFormField 2 in focus? $inFocus');
},
child: TextFormField(
focusNode: node1,
textInputAction: TextInputAction.next,
decoration: InputDecoration(hintText: 'Hint goes here 2'),
),
),
],
),
),
),
),
),
);
}
}
Answered By - Aby Bermen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.