Flutter setState 到另一个 class?

Flutter setState to another class?

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

示例代码

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'),
    );
  }
}

我确信有一个明显的答案,但我似乎无法弄清楚如何有效地做到这一点,以便集成未来的 classes 并使我的 Root 始终可见。

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

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'),
    );
  }
}

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

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

想法很简单,但实现起来 "little bit" 更复杂

实际上最有效的方法是在 flutter 中使用 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

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

让我们先用名称 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 是有状态小部件的一个属性,我们已将此代码编写在不同的文件中

问题已解决......:)

屏幕截图(空安全):


完整代码:

这是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)'),
    );
  }
}