I have a page with several text fields, I used FocusTraversalGroup
so the fields are focused in the desired order when pressing tab. See:
Now, when I click on the icon button next
, I want to send the focus to the next field.
For example, if I click on the icon button next
of the text field 3
, I want the text field 4 to be focused. For that, I tried to use focusNode.nextFocus()
, but the focus is sent to the text field 1 instead.
See the video:
Here is my code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Row(
children: [
Expanded(
child: FocusTraversalGroup(
child: Column(
children: <Widget>[
TextFormField(
decoration: const InputDecoration(label: Text('1')),
),
TextFormField(
decoration: const InputDecoration(label: Text('2')),
),
const _Field(
decoration: InputDecoration(label: Text('3')),
),
TextFormField(
decoration: const InputDecoration(label: Text('4')),
),
TextFormField(
decoration: const InputDecoration(label: Text('5')),
),
],
),
),
),
const SizedBox(width: 20),
Expanded(
child: FocusTraversalGroup(
child: Column(
children: <Widget>[
TextFormField(
decoration: const InputDecoration(label: Text('6')),
),
TextFormField(
decoration: const InputDecoration(label: Text('7')),
),
const _Field(
decoration: InputDecoration(label: Text('8')),
),
TextFormField(
decoration: const InputDecoration(label: Text('9')),
),
TextFormField(
decoration: const InputDecoration(label: Text('10')),
),
],
),
),
),
],
),
),
);
}
}
class _Field extends StatefulWidget {
const _Field({
this.decoration,
});
final InputDecoration? decoration;
@override
State<_Field> createState() => __FieldState();
}
class __FieldState extends State<_Field> {
final focusNodeText = FocusNode();
final focusNodeButton = FocusNode();
@override
void dispose() {
focusNodeText.dispose();
focusNodeButton.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FocusTraversalGroup(
child: Stack(
children: [
TextFormField(
decoration: widget.decoration,
focusNode: focusNodeText,
),
Positioned(
right: 0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
focusNode: focusNodeButton,
icon: const Icon(Icons.skip_next),
onPressed: () {
focusNodeButton.nextFocus();
},
),
],
),
),
],
),
);
}
}
What am I missing?
you can call
FocusScope.of(context).requestFocus(nextFocus);
with onPressed of the icon like this: