【问题标题】:Flutter/Dart - How can I change the State of a StatefulWidget from another StatefulWidget in a different file?Flutter/Dart - 如何从不同文件中的另一个 StatefulWidget 更改 StatefulWidget 的状态?
【发布时间】:2021-07-01 23:31:32
【问题描述】:

背景:我有一个用于导航栏的 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() 来解决它,但这不起作用,据我了解,它创建了另一个与 Stateful Widget 关联的 State 对象,这看起来像在这种情况下是错误的方法,因为我只想更改现有导航栏对象的状态。
我的问题是:如何从位于不同文件中的另一个 StatefulWidget 内的 Button 函数成功调用此函数 updateIndex(int index),它使用 setState 更新导航栏活动图标?

【问题讨论】:

    标签: flutter dart setstate statefulwidget


    【解决方案1】:

    我成功了! 根据对这个问题(Controlling State from outside of a StatefulWidget)的回答,我了解到访问不同 Stateful 小部件的 State 的方法是:

    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-> 这个函数应该位于你之前提到的有状态小部件的状态类里面,然后就可以正常使用setState了。例如:

    void updateIndexFromCart(int index) {
    setState(() {
      controller.index = index;
      cartScreenFlag = true;
    });
    

    }

    【讨论】:

      猜你喜欢
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      相关资源
      最近更新 更多