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

Gra*_*ham 5 flutter

我在 Stable 分支中使用 Flutter 1.2.1。为了说明我的问题,假设我有页面 A 和 B。A 使用 导航到 B Navigator.push,B 使用 导航回Navigator.popA。两者都是有状态的小部件。

当我从 A 导航到 B 然后返回到 A 时,一切都很好并且 A 保持其状态。但是,如果我从 A 导航到 B,点击 B 中的文本字段打开键盘,然后关闭键盘并弹回到 A,A 的整个状态将刷新,并initState()再次调用 A 的方法。我通过使用 print 语句验证了这一点。

仅当我在弹出回 A 之前打开键盘时才会发生这种情况。如果我导航到 B,然后立即导航回 A,而不与任何内容交互,则 A 会保持其状态并且不会重新初始化。

根据我的理解,构建方法一直被调用,但initState()不应该像这样被调用。有谁知道发生了什么事吗?

Gra*_*ham 5

经过多次尝试和错误,我确定了问题所在。我忘记了我已经在我的小部件中设置了FutureBuilder路线。我传递了一个函数调用,该函数调用将 future 返回给构造函数的参数,而不是指向 future 的变量。/MaterialAppfutureFutureBuilder

因此,每次路线更新时,都会创造一个全新的未来。在构造函数之外进行函数调用MaterialApp并将结果存储在变量中,然后将其传递给 就FutureBuilder可以了。

这似乎与键盘打开时出现的奇怪行为无关,但这绝对是原因。请参阅下文了解我的意思。

有错误的代码:

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) {
          ...
          }
      ...
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

固定代码:

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) {
          ...
          }
      ...
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)