我遇到了一个非常奇怪的Flutter bug,也许有人对此有所了解。
目前Flutter没有一个很好的自动从表单中的一个TextField移动到下一个TextField的方法。推荐的解决方案是为每个TextField创建一个FocusNode,然后当用户完成编辑时,通过编程方式选择下一个FocusNode。
这个方法似乎运行得很好,但如果您的表单不在应用程序的第一路线上(这更常见),它也会导致一些非常奇怪的视觉故障。
在第二个路线上,只要您点击一个TextField,装饰就会瞬间闪烁然后消失,但光标将保持不变。您可以继续选择TextField,最终每个字段都会有一个光标。虽然字段仍然可以正常使用,但这只是一个视觉故障。
问题似乎与Navigator密切相关。如果您在第一条路线上创建一个具有自定义FocusNodes的屏幕,则其行为良好。相反,如果您在第二个屏幕上不使用FocusNodes,则它也是fine的。只有当您同时组合它们时才会出现问题。
这是一个展示这个问题的简单应用程序。
import 'package:flutter/material.dart';
void main() {
runApp(TestApp());
}
class TestApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: TestScreen(),
);
}
}
class TestScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: RaisedButton(
onPressed: () => _pushSecondScreen(context),
child: Text('Push to a new screen')
),
),
)
);
}
void _pushSecondScreen(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => SecondTest()));
}
}
class SecondTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: ListView(
padding: EdgeInsets.all(20.0),
children: List<Widget>.generate(10, (i) => _buildTextField(i)),
),
);
}
Widget _buildTextField(int index) {
// The custom focus node is thrown in here for example, but in a real world app,
// a reference to the node would be kept so the app can manage focus between the nodes
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: TextField(
focusNode: FocusNode(),
decoration: InputDecoration(
labelText: 'Field $index',
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0))
)
),
),
);
}
}
我在这个gist上发布了代码以复制此问题: https://gist.github.com/bkayfitz-cara/8da2afd964c7f4417435e9df49b4cd9e