Flutter 打开键盘会导致有状态小部件重新初始化
我在稳定分支中使用的是颤振1.2.1。为了说明我的问题,假设我有A页和B页。A使用Flutter 打开键盘会导致有状态小部件重新初始化,flutter,Flutter,我在稳定分支中使用的是颤振1.2.1。为了说明我的问题,假设我有A页和B页。A使用Navigator导航到B。按下,B使用Navigator.pop导航回A。两者都是有状态的小部件 当我从A导航到B,然后弹回到A时,一切正常,A保持其状态。但是,如果我从A导航到B,点击B中的文本字段打开键盘,然后关闭键盘并弹回到A,A的整个状态将刷新,A的initState()方法将再次调用。我用打印语句验证了这一点 只有在弹出返回A之前打开键盘时才会发生这种情况。如果我导航到B,然后立即导航回A,而不与任何内
Navigator导航到B。按下,B使用Navigator.pop
导航回A。两者都是有状态的小部件
当我从A导航到B,然后弹回到A时,一切正常,A保持其状态。但是,如果我从A导航到B,点击B中的文本字段打开键盘,然后关闭键盘并弹回到A,A的整个状态将刷新,A的initState()
方法将再次调用。我用打印语句验证了这一点
只有在弹出返回A之前打开键盘时才会发生这种情况。如果我导航到B,然后立即导航回A,而不与任何内容交互,那么A将保持其状态,并且不会重新初始化
据我所知,build方法一直被调用,但是initState()
不应该像这样被调用。有人知道发生了什么吗?您在“A”小部件中使用过吗?
如果你没有,看看这个
如果您已经在使用它,请给我们一个代码,我们可以直接在“main.dart”中测试它,以帮助您经过多次尝试和错误后,我确定了这个问题。我忘记在我的MaterialApp
小部件中为/
路径设置了FutureBuilder
。我正在传递一个函数调用,该调用将未来返回到FutureBuilder
构造函数的future
参数,而不是指向未来的变量
因此,每次路线得到更新,一个全新的未来正在创造。在MaterialApp
构造函数之外进行函数调用,并将生成的未来存储在一个变量中,然后将其传递给FutureBuilder
这似乎与我打开键盘时的奇怪行为无关,但这肯定是原因。我的意思见下文
带有bug的代码:
return MaterialApp(
title: appTitle,
theme: ThemeData(
primarySwatch: Colors.teal,
accentColor: Colors.tealAccent,
buttonColor: Colors.lightBlue,
),
routes: {
'/': (context) => FutureBuilder<void>(
future: futureFun(), //Bug! I'm passing a function that returns a future when called. So a new future is returned each time
builder: (context, snapshot) {
...
}
...
}
...
}
return MaterialApp(
标题:appTitle,
主题:主题数据(
primarySwatch:Colors.teal,
accentColor:Colors.tealacent,
按钮颜色:颜色。浅蓝色,
),
路线:{
“/”:(上下文)=>FutureBuilder(
future:futureFun(),//Bug!我正在传递一个函数,该函数在调用时返回一个future。因此,每次都会返回一个新的future
生成器:(上下文,快照){
...
}
...
}
...
}
固定代码:
final futureVar = futureFun(); //calling the function here instead and storing its future in a variable
return MaterialApp(
title: appTitle,
theme: ThemeData(
primarySwatch: Colors.teal,
accentColor: Colors.tealAccent,
buttonColor: Colors.lightBlue,
),
routes: {
'/': (context) => FutureBuilder<void>(
future: futureVar, //Fixed! Passing the reference to the future rather than the function call
builder: (context, snapshot) {
...
}
...
}
...
}
final futureVar=futureFun();//在此处调用函数,并将其未来存储在变量中
返回材料PP(
标题:appTitle,
主题:主题数据(
primarySwatch:Colors.teal,
accentColor:Colors.tealacent,
按钮颜色:颜色。浅蓝色,
),
路线:{
“/”:(上下文)=>FutureBuilder(
future:futureVar,//Fixed!将引用传递给future而不是函数调用
生成器:(上下文,快照){
...
}
...
}
...
}
是的,发生在我身上,也许把FutureBuilder包装成一个PageWidget,使其成为一个单独的组件要好得多
return MaterialApp(
标题:appTitle,
主题:主题数据(
primarySwatch:Colors.teal,
accentColor:Colors.tealacent,
按钮颜色:颜色。浅蓝色,
),
路线:{
“/”:(上下文)=>PageWidget()//按PageWidget包装
...
}
...
}
类PageWidget扩展了无状态Widget{
静态final _instance=PageWidget._internal();//保持实例
PageWidget._internal();//内部构造函数
factory PageWidget(){
return _instance;//设为singleton
}
@凌驾
小部件构建(构建上下文){
returnfuturebuilder(…);
}
}
我得到了一个解决方案,我在超类的构造函数中初始化变量。我删除了它并开始工作!谢谢你的回答。我直到今天早上才尝试。它不起作用。当键盘打开时,似乎发生了一些事情,导致所有内容都被重新创建。这在版本之前没有发生过在1.2中,可能是一个bug,请尝试通过以下公开问题报告Flatter团队:[