Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 打开键盘会导致有状态小部件重新初始化_Flutter - Fatal编程技术网

Flutter 打开键盘会导致有状态小部件重新初始化

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,而不与任何内

我在稳定分支中使用的是颤振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,而不与任何内容交互,那么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团队:[