flutter - 在 Flutter 中切换页面时如何保持 Future 的值?
问题描述
当未来在屏幕 1 中有数据时,我正在尝试向屏幕添加一个小部件。
class UserChoiceBooks extends StatelessWidget {
final String title;
UserChoiceBooks({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Provider.of<Books>(context, listen: false)
.getRecommendedBooks("test"),
builder: (ctx, snapshot) {
// Checking if future is resolved
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final List<Book> recommendedBooksML = snapshot.data;
return BookList(title, recommendedBooksML);
} else {
return SizedBox.shrink();
}
} else {
return Container();
}
}
// ... some code here
);
}
}
我导航到另一个屏幕屏幕 2。然后返回屏幕 1。我丢失了未来的数据,它再次开始构建。
PS:我通过将未来数据存储在全局变量中找到了一个临时解决方法
List<Book> placeholder=[];
然后从未来设置值......placeholder=snapshot.data;
在屏幕 1 和 2 之间切换时。我正在检查
placeholder==[]?UserChoiceBooks (title):BookList(title,placeholder)
有没有更好的方法来保留快照中的数据,以便在屏幕未来值之间切换不会丢失?
解决方案
您在构建期间拨打电话:
Provider.of<Books>(context, listen: false).getRecommendedBooks("test")
因此,当屏幕重建时,它会再次被调用。你太幸运了,这两个导航之间没有发生其他重建,因为理论上它们是可能的。
推荐的心态是重建可能发生在每一帧,非重建帧应被视为框架优化。
因此,您应该拨打一次电话并保存。有几个选项:
在树的某处创建
Books
并将其传递给小部件。然后让你的小部件有状态并调用widget.books.getRecommendedBooks
它的initState()
.如果
Books
是单例,您可以使用像https://pub.dev/packages/get_it这样的服务定位器来实例化它一次,然后用于GetIt.instance.get
在您的小部件中的任何位置获取此实例。服务定位器模式比提供者模式有一些优势。一种讨厌的方法是在有状态小部件的状态下调用未来,并在首次构建时调用该方法 if
_future == null
。
对于有状态的小部件,请参阅本教程:https ://flutter.dev/docs/development/ui/interactive#stateful-and-stateless-widgets
另请注意,您应该将 a用于这样的小部件,对于传递给构造函数key
的不同 s 将有所不同。title
否则,当您将您的小部件替换为另一个title
时,框架将不知道接下来的所有内容都是针对另一本书的,并且不会创建新状态,因此initState()
不会被调用。
推荐阅读
- exception - System.IO.FileLoadException:在 RichEditBox 文档中引发异常
- c# - 如何在 Azure Devops 中使用服务帐户模拟用户
- json - 使用 jq 命令行处理器时 JSON 格式的问题
- sql - 偏移量不适用于 Count(*) 作为 order by
- javascript - 从上传的图片生成 DataURI 并添加到 PDF (JsPDF)
- docker - 什么是 Docker 中的悬空图像/它们如何创建/如何删除它们
- gnuplot - 如何在编码iso_8859_1中写希腊后者?
- c++ - 将 8bpp 位图转换为 32bpp 位图 C++
- c# - 为新的 WEB Api 应用程序搭建控制器时出错
- c# - 无论如何在该方法中的等待调用完成之前执行该方法的返回语句