【问题标题】:Flutter setState to another class?Flutter setState 到另一个类?
【发布时间】:2019-01-18 18:39:08
【问题描述】:

我有一个根类RootPage,它是一个始终可见的StatefulWidget。我想更改RootPage 中的body,它由来自不同类的RootPage's currentPage Widget 控制,例如我的FeedPage 类和我制作的任何其他类?

示例代码

import 'package:flutter/material.dart';

class RootPage extends StatefulWidget {
  @override
  _RootPageState createState() => new _RootPageState();
}
class _RootPageState extends State<RootPage> {
  FeedPage feedPage;

  Widget currentPage;

  @override
  void initState() {
    super.initState();
    feedPage = FeedPage();

    currentPage = feedPage;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      //Current page to be changed from other classes too?
      body: currentPage
    );
  }
}



class FeedPage extends StatefulWidget {
  @override
  _feedPageState createState() => new _feedPageState();
}
class _feedPageState extends State<FeedPage> {

  @override
  Widget build(BuildContext context) {
    return new FlatButton(
      onPressed: () {
        setState(() {
          //change the currentPage in RootPage so it switches FeedPage away and gets a new class that I'll make
        });
      },
      child: new Text('Go to a new page but keep root, just replace this feed part'),
    );
  }
}

我确信有一个明显的答案,但我似乎无法弄清楚如何有效地做到这一点,因此很容易集成未来的课程并让我的 Root 始终可见。

【问题讨论】:

    标签: dart flutter setstate


    【解决方案1】:

    您可以使用回调函数来实现这一点。请参考以下代码。

    import 'package:flutter/material.dart';
    
    class RootPage extends StatefulWidget {
      @override
      _RootPageState createState() => new _RootPageState();
    }
    class _RootPageState extends State<RootPage> {
      FeedPage feedPage;
    
      Widget currentPage;
    
      @override
      void initState() {
        super.initState();
        feedPage = FeedPage(this.callback);
    
        currentPage = feedPage;
      }
    
      void callback(Widget nextPage) {
        setState(() {
          this.currentPage = nextPage;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          //Current page to be changed from other classes too?
            body: currentPage
        );
      }
    }
    
    
    
    class FeedPage extends StatefulWidget {
      Function callback;
    
      FeedPage(this.callback);
    
      @override
      _feedPageState createState() => new _feedPageState();
    }
    class _feedPageState extends State<FeedPage> {
    
      @override
      Widget build(BuildContext context) {
        return new FlatButton(
          onPressed: () {
            this.widget.callback(new NextPage());
    //        setState(() {
    //          //change the currentPage in RootPage so it switches FeedPage away and gets a new class that I'll make
    //        });
          },
          child: new Text('Go to a new page but keep root, just replace this feed part'),
        );
      }
    }
    

    这与problem 非常相似,您可以参考我的回答中的第三点。

    【讨论】:

    • 你在 'this.widget.callback(new NextPage());' 中所做的回调是 'setState(){}' 还是你都需要?
    • 您是在问this.widget.callback(new NextPage()); 下方的评论setState 吗?
    • 而不是 setState。我们在那里不需要 setState。
    • @DineshBalasubramanian,我正在尝试做同样的事情,但我得到“无法在初始化程序中访问实例成员'回调'。”所以基本上,我必须回调静态,能够将其作为 arg 传递给其他屏幕,这意味着我不能在其中使用 setState 。关于如何解决这个问题的任何建议?
    • 显然,必须在 initState() 中调用构造函数才能工作。
    【解决方案2】:

    屏幕截图(Null 安全):


    完整代码:

    这是ParentPage

    class ParentPage extends StatefulWidget {
      @override
      _ParentPageState createState() => _ParentPageState();
    }
    
    class _ParentPageState extends State<ParentPage> {
      int _count = 0;
    
      // Pass this method to the child page.
      void _update(int count) {
        setState(() => _count = count);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              Text('Value (in parent) = $_count'),
              ChildPage(update: _update),
            ],
          ),
        );
      }
    }
    

    这是ChildPage

    class ChildPage extends StatelessWidget {
      final ValueChanged<int> update;
      ChildPage({required this.update});
    
      @override
      Widget build(BuildContext context) {
        return ElevatedButton(
          onPressed: () => update(100), // Passing value to the parent widget.
          child: Text('Update (in child)'),
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      我知道您需要针对您的特定代码的解决方案,但我建议您查看 BloC 模式,因为当您想将状态更改从小部件传递到另一个特别是多个页面时,它是推荐的方法

      这个想法很简单,尽管实现起来“有点”复杂

      【讨论】:

        【解决方案4】:

        这是一个棘手的问题,但我得到了这个问题的解决方案,我多次遇到这个问题。因此,让我们首先解决您的问题。这就是您的代码的解决方案

        让我们先用名称 feedPage.dart 保存这个文件

        `import 'package:flutter/material.dart';
        class FeedPage extends StatefulWidget {
          @override
          _feedPageState createState() => new _feedPageState();
        }
        class _feedPageState extends State<FeedPage> {
        
          @override
          Widget build(BuildContext context) {
            return new FlatButton(
              onPressed: () {
                setState(() {
                  //change the currentPage in RootPage so it switches FeedPage away and gets a new class that I'll make
                });
              },
              child: new Text('Go to a new page but keep root, just replace this feed part'),
            );
          }
        }`
        

        然后将该文件导入您的主文件中

        `
         import 'package:flutter/material.dart';
         import 'feedPage.dart'
        class RootPage extends StatefulWidget {
          @override
          _RootPageState createState() => new _RootPageState();
        }
        class _RootPageState extends State<RootPage> {
          FeedPage feedPage;
        
          Widget currentPage;
        
          @override
          void initState() {
            super.initState();
            feedPage = FeedPage();
        
            currentPage = feedPage;
          }
        
          @override
          Widget build(BuildContext context) {
            return new Scaffold(
              //Current page to be changed from other classes too?
              body: currentPage
            );
          }
        }`
        

        在 Flutter 中,您不能在一个 dart 文件中编写多个有状态小部件,您必须将其创建为小部件并在您的代码中使用它,因为 setState 是有状态小部件的属性,我们已将此代码写入不同的文件中

        问题解决了......:)

        【讨论】:

          【解决方案5】:

          实际上最有效的方法是在 Flutter 中使用 BLoC 包,并从小部件树的顶部实现它,这样所有继承的小部件都可以使用相同的 bloc。 如果您以前使用过 Android - 它的工作方式类似于 Android 架构组件 - 您将数据和状态管理与 UI 分开 - 因此您无需在 UI 中设置状态,而是使用 BLoC 来管理状态。 因此,您可以设置和访问相同的数据 - 从任何从实现 BLoC 的顶部小部件继承的小部件中设置和访问,对于更复杂的应用程序,它非常有用。

          你可以在这里找到包: https://pub.dev/packages/flutter_bloc#-readme-tab-

          撰写: https://www.didierboelens.com/2018/08/reactive-programming-streams-bloc/

          还有一个很棒的 youtube 教程 https://www.youtube.com/watch?v=hTExlt1nJZI&list=PLB6lc7nQ1n4jCBkrirvVGr5b8rC95VAQ5&index=7

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-03
            • 2019-07-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多