背景:我有一个用于导航栏的 StatefulWidget,用于将当前页面的图标显示为活动状态。如果用户从导航栏中单击不同的图标,它已经正确更新。但是,如果用户单击导航栏外部的按钮(其代码位于不同的 StatefulWidget 中),我还需要它来更新活动图标。 为此,我设想按钮的功能应该从导航栏 StatefulWidget 调用一个函数,该函数使用 setState 和作为参数传递的索引来更新活动图标。但是,到目前为止,我的尝试都没有奏效。 出现以下错误:
<块引用>处理手势时抛出以下断言:
I/flutter (24216): setState() 在构造函数中调用:TabsState#1bf6b(生命周期状态:已创建,无小部件,未安装)
I/flutter (24216):当您在 State 对象上为尚未插入的小部件调用 setState() 时会发生这种情况
I/flutter (24216):小部件树呢。没有必要在构造函数中调用 setState(),因为状态是
I/flutter (24216):在最初创建时已经假定它是脏的。`}
来自父小部件的代码是:
[...]
Tabs({Key key, this.menuScreenContext, this.initialIndex}) : super(key: key);
final int initialIndex;
@override
TabsState createState() => TabsState();
}
class TabsState extends State<Tabs> {
PersistentTabController controller;
@override
void initState() {
super.initState();
controller = PersistentTabController(initialIndex: widget.initialIndex);
}
List<Widget> _buildScreens() {
return [
HomeScreen(),
[...]
void updateIndex(int index) {
setState(() {
controller.index = index;
});
}
}
来自子小部件的代码(类 _HomeScreenState 扩展 State ):
[...]
CustomButton(
function: () {
final tabsState = TabsState();
tabsState.updateIndex(2);
[...]
我试图通过在调用 setState() 之前在子小部件上调用 initState() 来解决它,但这不起作用,据我所知,它创建了另一个与有状态小部件关联的状态对象,这似乎是在这种情况下的错误方法,因为我只想更改现有导航栏对象的状态。
我的问题是:我怎样才能成功调用这个函数 updateIndex(int index),它使用 setState 来更新导航栏活动图标,从另一个 StatefulWidget 内的 Button 函数,位于不同的文件中,成功?
答案 0 :(得分:0)
我做到了! 根据这个问题(Controlling State from outside of a StatefulWidget)的答案,我了解到访问不同有状态小部件的状态的一种方法是:
1-> 使用 findAncestorStateOfType 在子小部件有状态小部件上声明要更改的 State 类,它会查找该类型的祖先。例如:
class HomeScreen extends StatefulWidget {
static TabsState of(BuildContext context) =>context.findAncestorStateOfType<TabsState>();
2-> 在这个有状态小部件的状态类中从任何你需要的地方调用该函数,参考有状态小部件类并使用“of(context)”。例如:
function: () {
HomeScreen.of(context).updateIndexFromCart(2);
3-> 这个函数应该在你之前提到的stateful widget的state类里面,然后就可以正常使用setState了。例如:
void updateIndexFromCart(int index) {
setState(() {
controller.index = index;
cartScreenFlag = true;
});
}