在Flutter中使用WillPopScope*

在Flutter中使用WillPopScope

作者:坚果

公众号:“大前端之旅

华为云享专家,InfoQ签约作者,OpenHarmony布道师,,华为云享专家,阿里云专家博主,51CTO博客首席体验官,开源项目GVA成员之一,专注于大前端技术的分享,包括Flutter,鸿蒙,小程序,安卓,VUE,JavaScript。

突然,在阅读特定内容时,。令人惊讶的是,您发现您的手指掠过后退按钮。页面弹出,

这可能不是什么大问题,如果您可以前进到页面并从您停止的地方继续,但如果应用程序已刷新屏幕或设置为在您进入页面时显示更新的内容 ,然后,您会丢失屏幕上的位置或滚动浏览该特定内容时所在的位置。

这样会对整体用户体验产生影响。在构建应用程序时,应该采取措施防止这些情况出现在你的应用程序里。

什么是WillPopScope小部件?

 WillPopScope WillPopScope({WillPopScope WillPopScope({
    required Widget child,Widget child,
    required Future<bool> Function()? onWillPop,Future<bool> Function()? onWillPop,
  })})

Flutter 框架自该WillPopScope小部件 。它使我们可以控制后退按钮的操作,如果当前页面满足某些要求,则可以返回到上一个页面。这是使用回调实现的,小部件将其作为其参数之一。

Flutter 官方文档中所述,该小部件:

注册回调以否决用户试图解除封闭的尝试ModalRoute

使用WillPopScope小部件,您可以有效地防止类似于上面描述的情况:通过提供额外的验证方式,用户可以选择取消/防止当前页面弹出,即返回。

WillPopScope部件需要两个参数:

  • 回调:onWillPop处理操作并确定页面是否应该弹出或不使用布尔值;如果为真,则页面弹回,如果不是,则保留在同一页面上
  • child部件:视图的小部件

在 Flutter 应用中如何使用WillPopScope

我们将构建一个示例应用程序来演示WillPopScope小部件的运行情况。示例应用程序包含两个页面,即homeViewcontentView

WillPopScope将捕获后退按钮并在此视图上单击后退按钮时执行操作。如前所述,该WillPopScope小部件有一个回调,在其中我们将显示一个带有问题的提示对话框(您要返回吗?)和两个操作选项(一个按钮和一个按钮)。这些动作决定了页面是否应该弹出。

弄清楚了,让我们开始编码。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: "大前端之旅",
      home: HomeView(),
    );
  }
}

class HomeView extends StatelessWidget {
  const HomeView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text('HomeView'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const Text(
              'HomeView',
              style: TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(
              height: 24,
            ),
            TextButton(
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
              ),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) {
                      return const ContentView();
                    },
                  ),
                );
              },
              child: const Text(
                'Go To ContentView',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ContentView extends StatelessWidget {
  const ContentView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        final shouldPop = await showDialog<bool>(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: const Text('Do you want to go back?'),
              actionsAlignment: MainAxisAlignment.spaceBetween,
              actions: [
                TextButton(
                  onPressed: () {
                    Navigator.pop(context, true);
                  },
                  child: const Text('Yes'),
                ),
                TextButton(
                  onPressed: () {
                    Navigator.pop(context, false);
                  },
                  child: const Text('No'),
                ),
              ],
            );
          },
        );

        return shouldPop!;
      },
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: const Text('Content View'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: const [
              Text(
                'This is the Content View',
                style: TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

好的,编码完成,大家可以自己运行,体验一下效果。

image-20220514103007922

image-20220514103032783

image-20220514103052020

  • 掘金:https://juejin.cn/user/3843548384077192
  • InfoQ:https://xie.infoq.cn/article/a6704ba471cbea84320d2c7c4
  • 51CTO博客https://blog.51cto.com/jianguo
  • CSDN:https://blog.csdn.net/qq_39132095?spm=1000.2115.3001.5343

猜你喜欢

转载自blog.csdn.net/qq_39132095/article/details/124764909
今日推荐