如何调用一个无状态小部件的重建?
如何调用一个无状态小部件的重建?
背景
\n我有两个无状态的小部件(页面):HomePage
和DetailsPage
。显然应用程序在HomePage
上启动和运行。用户可以按下按钮导航到DetailsPage
,然后使用Navigator.pop()
按钮导航回HomePage
。\n我知道DetailsPage
在使用完毕时可以使用.whenComplete()
方法。此时我想重新构建HomePage
小部件。\n
代码
\n这是我行为的最小复现。\nmain.dart
\nimport \'package:example/home.dart\';\nimport \'package:flutter/material.dart\';\nvoid main() => runApp(MyApp());\nclass MyApp extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return MaterialApp(home: HomePage());\n }\n}\n
\nhome.dart
\nimport \'package:example/details.dart\';\nimport \'package:flutter/material.dart\';\nclass HomePage extends StatelessWidget {\n static const name = \'首页\';\n const HomePage() : super();\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n body: Center(\n child: MaterialButton(\n color: Colors.blue,\n textColor: Colors.white,\n child: Text(name),\n onPressed: () {\n Navigator.push(\n context,\n MaterialPageRoute(builder: DetailsPage.builder),\n ).whenComplete(() => print(\'重新构建。\'));\n },\n ),\n ),\n );\n }\n}\n
\ndetails.dart
\nimport \'package:flutter/material.dart\';\nclass DetailsPage extends StatelessWidget {\n static const name = \'详情页\';\n static WidgetBuilder builder = (BuildContext _) => DetailsPage();\n const DetailsPage();\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n body: Center(\n child: Column(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n Text(name),\n MaterialButton(\n color: Colors.blue,\n textColor: Colors.white,\n child: Text(\'返回\'),\n onPressed: () => Navigator.pop(context),\n ),\n ],\n ),\n ),\n );\n }\n}\n
\n
问题
\n如何在.whenComplete()
方法回调中调用此无状态小部件(HomePage
)的重新构建?
如何调用一个无状态小部件的重建?
问题原因:无状态小部件不会自动重建,因此需要手动触发重建。
解决方法:可以使用全局键(GlobalKey)和访问子元素的方式来强制重建小部件树。具体实现方法如下:
1. 创建一个RebuildController类,包含一个全局键rebuildKey和一个rebuild方法。
2. 在rebuild方法中,通过遍历子元素的方式标记它们需要重建,并递归调用rebuild方法。
3. 创建一个RebuildWrapper无状态小部件,接收一个RebuildController和一个子部件作为参数。
4. 在RebuildWrapper的build方法中,使用controller.rebuildKey作为Container的键,并将子部件作为其子部件。
5. 在主函数中,创建一个RebuildController实例,并将其作为参数传递给RebuildWrapper小部件。
6. 在HomePage小部件的onPressed回调中,通过Navigator.push和whenComplete方法来触发重建。
但是,由于无状态小部件不应该被强制重建,因此更好的解决方法是使用有状态小部件或其他状态管理解决方案来实现有意义的状态更改时才更新HomePage小部件。
来源:Stack Overflow上的一个回答
这个解决方案很有道理。我同意你的观点。在不使用真正的状态管理的情况下,这个问题确实没有解决方法。不过,这个方法还是很有趣的。
我很高兴能帮到你!我也考虑过使用RepaintBoundary,但它不能重建小部件,这与你想要的行为不符。