dart 如何使用Navigator.pop()在显示屏幕之前更新它?

dsf9zpds  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(151)

我在应用程序的每个屏幕上都有一个开关,可以在整个应用程序中启用/禁用黑暗模式。
我尝试使用Navigator.push()导航到第二个屏幕,和Navigator.pop()回去,这是很简单的.但是...
我总是面临同样的问题。我看到第一页在我的脸上更新后,弹出()动画完成。这是奇怪的外观(像眨眼)。重点是:当我回到第一页时,我想看到我已经在那里做的更改。
这是代码,以防你需要它。

//first_page.dart

import 'package:flutter/material.dart';
import 'second_page.dart';

class FirstPage extends StatefulWidget {
  const FirstPage({super.key, required this.darkMode});

  final bool darkMode;

  @override
  State<FirstPage> createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  late final ValueNotifier<bool> darkMode;

  @override
  void initState() {
    super.initState();

    darkMode = ValueNotifier(widget.darkMode);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(actions: [
        Switch(
          value: darkMode.value,
          onChanged: (bool newValue) {
            setState(
              () => darkMode.value = newValue,
            );
          },
        )
      ]),
      body: Container(
        color: darkMode.value ? Colors.white : Colors.black,
        child: Center(
          child: ElevatedButton(
            onPressed: () async {
              bool? isDark = await Navigator.push<bool?>(context,
                  MaterialPageRoute(builder: (context) {
                return SecondPage(
                  darkMode: darkMode.value,
                );
              }));

              setState(() {
                darkMode.value = isDark!;
              });
            },
            child: Text(
              "Go to page 2",
            ),
          ),
        ),
      ),
    );
  }
}
//second_page.dart

import 'package:flutter/material.dart';

class SecondPage extends StatefulWidget {
  const SecondPage({super.key, required this.darkMode});

  final bool darkMode;

  @override
  State<SecondPage> createState() => SecondPageState();
}

class SecondPageState extends State<SecondPage> {
  late final ValueNotifier<bool> darkMode;

  @override
  void dispose() {
    darkMode.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();

    darkMode = ValueNotifier(widget.darkMode);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(actions: [
        Switch(
          value: darkMode.value,
          onChanged: (bool newValue) async{
            setState(
              () => darkMode.value = newValue,
            );
          },
        )
      ]),
      body: Container(
        color: darkMode.value ? Colors.white : Colors.black,
        child: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.pop(context, darkMode.value);
            },
            child: Text(
              "Pop back",
            ),
          ),
        ),
      ),
    );
  }
}

我尝试过共享小部件,共享值通知器,从Navigator.pop(context,value)返回true/false...
我找到的唯一方法是使用Navigator.push到SecondScreen,它有一个按钮导航.push再次到FirstScreen。
我只是想知道我是否错过了什么...谢谢你的帮助!This GIF shows the issue I described

jgwigjjp

jgwigjjp1#

如果你使用Flutter Navigator,你可以在push方法之后使用whenComplete。它将在返回页面时执行代码(在另一个页面上的context.pop()之后)

示例

onPressed: () {
        Navigator.of(context)
            .push(
          SecondPage.route(darkMode: darkMode),
        )
            .whenComplete(() {
          // execute some code when returning to the page
        });
      },

文档

你也可以使用async函数。
docs

建议:为了使代码更简洁,您可以将MaterialPageRoute移动到SecondPage类中的单独方法(我们称之为route)。

class SecondPage extends StatelessWidget {
  const SecondPage({
    super.key,
    required this.darkMode,
  });

  final bool darkMode;

  static Route<void> route({
    required bool darkMode,
  }) {
    return MaterialPageRoute(
      builder: (context) => SecondPage(
        darkMode: darkMode,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold();
  }
}

相关问题