Flutter中WillPopScope导航返回拦截

Posted 伟雪无痕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter中WillPopScope导航返回拦截相关的知识,希望对你有一定的参考价值。

一.Flutter中WillPopScope简介

1.WillPopScope源码查看

  const WillPopScope(
    Key? key,
    required this.child, //页面显示的内容
    required this.onWillPop, //当前页面将退出
  ) 

onWillPop是一个回调函数,当用户点击返回按钮时被调用。该回调需要返回一个Future对象,如果返回的值为false,则当前路由不出栈(不会返回);反之为true时,则当前路由出栈退出。 

二.WillPopScope demo实现

1.点击两次时间间隔小于1S,退出当前页面

 DateTime? _lastQuitTime; //上次退出时间

  @override
  Widget build(BuildContext context) 

    return WillPopScope(
      onWillPop: () async 
        if (_lastQuitTime == null ||
            DateTime.now().difference(_lastQuitTime!).inSeconds > 1) 
          print('再按一次Back键退出');
          Scaffold.of(context)
              .showSnackBar(SnackBar(content: Text('再按一次Back键退出')));
          _lastQuitTime = DateTime.now();
          return false;
         else 
          print('退出');
          Navigator.of(context).pop(true);
          return true;
        
      ,
      child: Scaffold(

2. 方式二,点击两次退出

int lastTime = 0;

  Future<bool> doubleClickQuit() 
    int nowTime = DateTime.now().millisecondsSinceEpoch;
    if (nowTime - lastTime > 1000) 
      lastTime = DateTime.now().millisecondsSinceEpoch;
      return Future.value(false);
     else 
      return Future.value(true);
    
  

  @override
  Widget build(BuildContext context) 

    return WillPopScope(
      onWillPop: doubleClickQuit,
      child: Scaffold(

三.详细代码 MainPage.dart,其他代码需要引入,可参考链接:flutter底部导航栏

import 'package:flutter/material.dart';
import 'findpage.dart';
import 'mypage.dart';
import 'contactpage.dart';
import 'homepage.dart';
import 'mydrawer.dart';

class MainPage extends StatefulWidget
  const MainPage(Key? key) : super(key: key);

  @override
  State<StatefulWidget> createState()=>_MainPageState();


class _MainPageState extends State<MainPage>

  var allPages=[HomePage(),ContactPage(),FindPage(),MyPage()];
  var currentIndex=0;
  DateTime? _lastQuitTime; //上次退出时间

 /* int last = 0;

  Future<bool> doubleClickBack() 
    int now = DateTime.now().millisecondsSinceEpoch;
    if (now - last > 1000) 
      last = DateTime.now().millisecondsSinceEpoch;
      return Future.value(false);
     else 
      return Future.value(true);
    
  */


  @override
  Widget build(BuildContext context) 

    return WillPopScope(
      onWillPop: () async 
        if (_lastQuitTime == null ||
            DateTime.now().difference(_lastQuitTime!).inSeconds > 1) 
          print('再按一次Back键退出');
          Scaffold.of(context)
              .showSnackBar(SnackBar(content: Text('再按一次Back键退出')));
          _lastQuitTime = DateTime.now();
          return false;
         else 
          print('退出');
          Navigator.of(context).pop(true);
          return true;
        
      ,
      child: Scaffold(
        appBar: AppBar( //导航栏
          title: Text("App Name"),
          actions: <Widget>[ //导航栏右侧分享菜单
            IconButton(icon: Icon(Icons.share), onPressed: () ),
          ],
        ),
        drawer: MyDrawer(), //菜单抽屉
        body: allPages[currentIndex],
        backgroundColor: Colors.green,
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: currentIndex,
          type: BottomNavigationBarType.fixed,
          unselectedItemColor: Colors.grey,
          selectedItemColor: Colors.blue,
          /*unselectedLabelStyle:TextStyle(
          color: Colors.black
        ),*/
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: "首页",
              //backgroundColor:Colors.blue
            ),

            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: "通讯录",
              //backgroundColor:Colors.blue
            ),

            BottomNavigationBarItem(
              icon: Icon(Icons.find_in_page),
              label: "发现",
              //backgroundColor:Colors.blue
            ),

            BottomNavigationBarItem(
              icon: Icon(Icons.flip_outlined),
              label: "我的",
              //backgroundColor:Colors.blue
            ),
          ],

          onTap: (index)
            setState(() 
              print("the index is :$index");
              currentIndex=index;
            );
          ,
        ),

        floatingActionButton: FloatingActionButton( //悬浮按钮
            child: Icon(Icons.add),
            onPressed:_onAddNum
        ),
      ),
    );
   
  
  void _onAddNum()
  

以上是关于Flutter中WillPopScope导航返回拦截的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中使用带有 WillPopScope 的嵌套导航器

Flutter——两种监听导航栏返回按钮的方法

Flutter 功能型组件:WillPopScope

Flutter 专题28 易忽略的小而巧的技术点汇总 #yyds干货盘点#

Flutter WillPopScope 拦截路由返回

Flutter中如何使用WillPopScope