dart Flutter for Web:后退/前进按钮问题

vxqlmq5t  于 11个月前  发布在  Flutter
关注(0)|答案(4)|浏览(196)

我正面临以下问题:
我有一个StatefulWidget,它可以在状态更改时生成不同的视图:

class _HomePageState extends State<HomePage> {
  bool _changed = false;

  @override
  Widget build(BuildContext context) {
    return changed ? View2() : View1();
  }
}

字符串
如果我将状态_changed更改为true,然后单击后退按钮,然后单击前进按钮,我希望我的应用程序创建新的_HomePageState并显示View1,但当前显示的是View2,因此我认为状态以某种方式持久化。
如何强制重建小部件的状态?
出现问题的示例应用:link
复制步骤:
1.打开一些网站,例如www.google.com
1.将链接粘贴到应用程序https://issueapp.tiiny.site
1.通过按下按钮更改应用程序的状态
1.按浏览器的后退按钮
1.按浏览器的前进按钮
GIF呈现问题:


的数据
完整的代码再现了这个问题:

import 'package:flutter/material.dart';

void main() => runApp(const Application());

class Application extends StatelessWidget {
  const Application({super.key});

  @override
  Widget build(BuildContext context) => const HomePage();
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _changed = false;

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Text(_changed ? "CHANGED" : "NOT CHANGED"),
          ElevatedButton(
            onPressed: () { setState(() { _changed = !_changed; }); },
            child: const Text("CHANGE"),
          ),
        ],
      ),
    );
  }
}

nkkqxpd9

nkkqxpd91#

有几种方法可以做到这一点,现在最简单的方法是添加一个 Package 器作为父部件,当您从浏览器按下后退按钮时,它会接收回调,然后重新启动部件。
结果如下:


的数据
代码:

  • 你需要先调用MyParentWidget
  • 你可以使用任何小部件来刷新键,我只是为了简单而使用setState。
class MyParentWidget extends StatefulWidget {
  const MyParentWidget({
    super.key,
  });

  @override
  State<MyParentWidget> createState() => _MyParentWidgetState();
}

class _MyParentWidgetState extends State<MyParentWidget> {
  @override
  Widget build(BuildContext context) {
    return MyHomePage(
      key: UniqueKey(),
      onBackPressed: () {
        setState(() {});
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    required this.onBackPressed,
    super.key,
  });

  final VoidCallback onBackPressed;

  @override
  State<MyHomePage> createState() {
    return _MyHomePageState();
  }
}

class _MyHomePageState extends State<MyHomePage> {
  bool _changed = false;

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () => Future(() {
        widget.onBackPressed();
        return false;
      }),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Text(
            _textForCurrentState(),
            style: const TextStyle(
              color: Colors.black,
              decoration: TextDecoration.none,
            ),
          ),
          ElevatedButton(
            onPressed: () {
              setState(() {
                _changed = !_changed;
              });
            },
            child: const Text("CHANGE"),
          ),
        ],
      ),
    );
  }

  String _textForCurrentState() {
    return _changed ? "CHANGED" : "NOT CHANGED";
  }
}

字符串

velaa5lx

velaa5lx2#

这只会发生在flutter web的发布版本上。您的flutter web状态将保留在导航堆栈中,直到您刷新页面。
这里有一些来自flutter web问题的额外评论,与刷新浏览器重置导航堆栈和局部变量有关:
当您刷新页面时,整个应用程序将被销毁并再次启动。这就是浏览器的工作方式,这里没有任何特定于Flutter的内容。因此,局部变量的值预计会消失。
现在导航的工作方式是将导航堆栈保存在内存中,这意味着页面刷新时堆栈会被销毁,历史记录也会丢失。
在这里阅读mdebbar的github完整评论

ajsxfq5m

ajsxfq5m3#

这是因为你的屏幕没有变化,所以浏览器没有检测.你可以使用WillPopScope见下面的代码:

import 'package:flutter/material.dart';

void main() => runApp(const Application());

class Application extends StatelessWidget {
  const Application({super.key});

  @override
  Widget build(BuildContext context) => const HomePage();
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _changed = false;

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        setState(() {
          _changed = !_changed;
        });
        return false;
      },
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Text(_changed ? "CHANGED" : "NOT CHANGED"),
            ElevatedButton(
              onPressed: () { setState(() { _changed = !_changed; }); },
              child: const Text("CHANGE"),
            ),
          ],
        ),
      ),
    );
  }
}

字符串

siv3szwd

siv3szwd4#

只需将您的列 Package 为WillPopScope并为其willPopScope属性添加以下条件,

onWillPop: () async {
        setState(() {
          _changed;
        });
        return true;
      },

字符串
但是,我建议使用状态管理工具,如值通知器或更改通知器,以实现平稳的过程。

相关问题