简体   繁体   English

Flutter 在不同页面上同一小部件的两个实例之间同步 state

[英]Flutter sync state between 2 instances of the same widget on different pages

I have a question about my use case: assume we are currently on screen A which shows an instance of my chart-widget (amongst other things).我有一个关于我的用例的问题:假设我们当前在屏幕 A 上,它显示了我的图表小部件的一个实例(除其他外)。 I want to give the user the opportunity to show that chart on the full app-screen by allowing to tap on a "full-screen" button at the top-right.我想让用户有机会通过点击右上角的“全屏”按钮在整个应用程序屏幕上显示该图表。 On full screen button click, I push a new MaterialPageRoute and show the same widget instance of the chart on the whole screen (screen B).单击全屏按钮时,我推送一个新的MaterialPageRoute并在整个屏幕(屏幕 B)上显示图表的相同小部件实例。

However I miss something important, which is that the fullscreen widget should stay in sync with the original widget.但是我错过了一些重要的事情,那就是全屏小部件应该与原始小部件保持同步。 Ie if the user makes any modification in fullscreen, after closing the fullscreen mode, the original chart should be in the same state as the fullscreen chart.即如果用户在全屏模式下进行任何修改,关闭全屏模式后,原始图表应该与全屏图表在同一个state。 I currently don't know how to achieve this.我目前不知道如何实现这一目标。 I tried by using the same GlobalKey for both, but without luck.我尝试对两者使用相同的 GlobalKey,但没有成功。 Any hints?有什么提示吗?

Screen A:屏幕 A: 图表普通视图

Screen B:屏幕 B: 图表全屏视图

Some code:一些代码:

My Fullscreenable widget which enables to show any Widget on a on the full scaffold body within a new page:我的Fullscreenable小部件可以在新页面的完整脚手架主体上显示任何小部件:

class Fullscreenable extends StatelessWidget {
  final String name;
  final Widget child;

  const Fullscreenable({
    Key? key,
    required this.child,
    this.name = "",
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        child,
        Positioned(
          top: -12,
          right: -12,
          child: IconButton(
            // visualDensity: VisualDensity.compact,
            padding: EdgeInsets.zero,
            icon: const Icon(Icons.fullscreen),
            onPressed: () {
              Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (BuildContext context) => FullScreenView(
                      title: name,
                      child: child,
                    ),
                  // fullscreenDialog: true,
                ),
              );
            },
          ),
        )
      ],
    );
  }
}

Screen A:屏幕 A:

...
Column(
  children: [
    Fullscreenable(
      name: "This is the title",
      child: MyChart()
    ),
    ...
  ],
)
...

Screen B ( FullscreenView ):屏幕 B( FullscreenView ):

class FullScreenView extends StatelessWidget {
  final String title;
  final Widget child;

  const FullScreenView({Key? key, required this.child, this.title = ""})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        toolbarHeight: 48,
      ),
      body: child,
    );
  }
}

As a native solution, you can consider ValueNotifier and ValueListenableBuilder .作为本机解决方案,您可以考虑ValueNotifierValueListenableBuilder Or implement some state manager.或者实施一些 state 经理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM