Closed Lootwig closed 2 years ago
That's strange. @lulupointu can you think of anything that might be causing that behavior?
I did not but I investigated and I think this is because of AutofillGroup.dispose
which calls TextInput.finishAutofillContext
which removes the keyboard focus.
It's not that autofocus
does not work (you can actually see the textfield being focus during a few frames), it's rather that autofocus
acts before TextInput.finishAutofillContext
.
goNamed
with Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const Second()))
works ?When you do Navigator.of(context).push
it pushes on top of the First
widget. Therefore the First
widget is not disposed which means that TextInput.finishAutofillContext
is not called so autofocus
works.
AutofillGroup
on First
works?As I said, the problematic part is TextInput.finishAutofillContext
which is called in AutofillGroup.dispose
so removing AutofillGroup
does the trick.
The solution I found was to manually refocus the first time the TextField
is unfocused. The issue is that if you navigate to Second
from a screen which does not have a AutofillGroup.dispose
, then the first manual keyboard focus will be ignore. Maybe a timer to remove the listener might be good enough. Definitely not perfect though
Here is my Second
implementation:
class Second extends StatefulWidget {
const Second({Key? key}) : super(key: key);
@override
State<Second> createState() => _SecondState();
}
class _SecondState extends State<Second> {
final _focusNode = FocusNode();
@override
void initState() {
super.initState();
// Focus after un-focus
_focusNode.addListener(_refocusPlease);
}
_refocusPlease() {
if (!_focusNode.hasFocus) {
_focusNode.nextFocus();
_focusNode.removeListener(_refocusPlease);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextFormField(focusNode: _focusNode, autofocus: true),
),
);
}
}
Also I tried a few things like WidgetsBinding.instance.addPostFrameCallback
but this did not work. I think this is because of how Navigator
works (when a screen is removed, it is not removed directly but stays a few frames inside the widget tree to allow its out animation if any)
@Lootwig does you confirm that this solves your problem?
@lulupointu thanks!
@lulupointu thanks for looking into it, but the suggested implementation for Second
does not work very well:
@csells even if it's not a solution, I understand that this is not a GoRouter issue. Would appreciate your upvotes over at https://github.com/flutter/flutter/issues/96756!
Running the code below on flutter 2.8.1 in iOS 15.2 on the Simulator results in the keyboard closing immediately after navigating to the
Second
page.The behavior does not occur
goNamed
withNavigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const Second()))
AutofillGroup
onFirst
.Minimum working example
```dart import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { MyApp({Key? key}) : super(key: key); final _router = GoRouter( routes: [ GoRoute( path: '/', builder: (_, __) => const Home(), routes: [ GoRoute( name: '2', path: '2', builder: (_, __) => const Second(), ), GoRoute( name: '1', path: '1', builder: (_, __) => const First(), ), ], ), ], ); @override Widget build(BuildContext context) { return MaterialApp.router( routeInformationParser: _router.routeInformationParser, routerDelegate: _router.routerDelegate, ); } } class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override StateVideo (doesn't show in browser for me, but can be downloaded when copying address):
https://user-images.githubusercontent.com/39827040/149756670-80fb21ba-77dd-4ce0-8681-4a8a33bc47eb.mov