@@ -41,7 +41,10 @@ class RadioGroup extends StatefulWidget
41
41
42
42
@override
43
43
Map <String , Function > methods () {
44
- return {};
44
+ return {
45
+ 'focus' : () => _controller.radioGroupAction? .focusInputField (),
46
+ 'unfocus' : () => _controller.radioGroupAction? .unfocusInputField (),
47
+ };
45
48
}
46
49
47
50
@override
@@ -73,7 +76,12 @@ class RadioGroup extends StatefulWidget
73
76
}
74
77
}
75
78
79
+ mixin RadioGroupAction on FormFieldWidgetState <RadioGroup > {
80
+ void focusInputField ();
81
+ void unfocusInputField ();
82
+ }
76
83
class RadioGroupController extends FormFieldController {
84
+ RadioGroupAction ? radioGroupAction;
77
85
dynamic selectedValue;
78
86
79
87
// list of string for items
@@ -101,12 +109,43 @@ class RadioGroupController extends FormFieldController {
101
109
}
102
110
103
111
class RadioGroupState extends FormFieldWidgetState <RadioGroup >
104
- with TemplatedWidgetState {
112
+ with RadioGroupAction , TemplatedWidgetState {
105
113
List ? itemTemplateData;
114
+ FocusNode focusNode = FocusNode ();
115
+
116
+ @override
117
+ void initState () {
118
+ super .initState ();
119
+ focusNode.addListener (_handleFocusChange);
120
+ }
121
+
122
+ @override
123
+ void dispose () {
124
+ focusNode.removeListener (_handleFocusChange);
125
+ focusNode.dispose ();
126
+ super .dispose ();
127
+ }
128
+
129
+ void _handleFocusChange () {
130
+ // If gaining focus, scroll into view
131
+ WidgetsBinding .instance.addPostFrameCallback ((_) {
132
+ final context = validatorKey.currentContext;
133
+ if (context != null ) {
134
+ Scrollable .ensureVisible (
135
+ context,
136
+ duration: const Duration (milliseconds: 300 ),
137
+ curve: Curves .easeInOut,
138
+ alignment: 0.5 ,
139
+ );
140
+ }
141
+ });
142
+
143
+ }
106
144
107
145
@override
108
146
void didChangeDependencies () {
109
147
super .didChangeDependencies ();
148
+ widget.controller.radioGroupAction = this ;
110
149
111
150
if (widget._controller.itemTemplate != null ) {
112
151
registerItemTemplate (context, widget._controller.itemTemplate! ,
@@ -116,6 +155,20 @@ class RadioGroupState extends FormFieldWidgetState<RadioGroup>
116
155
}
117
156
}
118
157
158
+ @override
159
+ void focusInputField () {
160
+ if (! focusNode.hasFocus) {
161
+ focusNode.requestFocus ();
162
+ }
163
+ }
164
+
165
+ @override
166
+ void unfocusInputField () {
167
+ if (focusNode.hasFocus) {
168
+ focusNode.unfocus ();
169
+ }
170
+ }
171
+
119
172
@override
120
173
Widget buildWidget (BuildContext context) {
121
174
// build the children and gap if applicable
@@ -159,7 +212,9 @@ class RadioGroupState extends FormFieldWidgetState<RadioGroup>
159
212
return null ;
160
213
},
161
214
builder: (FormFieldState <String > field) {
162
- return InputDecorator (
215
+ return Focus (
216
+ focusNode: focusNode,
217
+ child: InputDecorator (
163
218
decoration: inputDecoration.copyWith (
164
219
contentPadding: EdgeInsets .zero,
165
220
filled: false ,
@@ -169,7 +224,8 @@ class RadioGroupState extends FormFieldWidgetState<RadioGroup>
169
224
focusedBorder: InputBorder .none,
170
225
errorText: field.errorText,
171
226
errorStyle: widget._controller.errorStyle ?? Theme .of (context).inputDecorationTheme.errorStyle),
172
- child: rtn);
227
+ child: rtn),
228
+ );
173
229
},
174
230
),
175
231
);
0 commit comments