You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现双击返回键关闭App并保留WebView返回功能?

解决方案

要同时实现WebView返回上一页和双击返回关闭App的功能,核心思路是优先让WebView处理返回操作,当WebView没有历史页面可返回时,再触发双击关闭App的逻辑。以下是具体实现步骤:

1. 添加依赖

在pubspec.yaml中添加所需依赖:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.4.0 # 使用最新稳定版即可
  double_back_to_close_app: ^2.2.0

2. 修改代码实现逻辑

将原StatelessWidget改为StatefulWidget(需要监听WebView的历史状态),结合PopScope和DoubleBackToCloseApp组件完成需求:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:double_back_to_close_app/double_back_to_close_app.dart';

final uri = Uri.parse('https://google.com');

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late final WebViewController controller;
  bool _canWebViewGoBack = false;

  @override
  void initState() {
    super.initState();
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(NavigationDelegate(
        onPageFinished: (String url) {
          print(url);
          // 页面加载完成后更新WebView可返回状态
          controller.canGoBack().then((value) {
            setState(() {
              _canWebViewGoBack = value;
            });
          });
        },
        // 监听页面导航,实时更新可返回状态
        onNavigationRequest: (request) {
          controller.canGoBack().then((value) {
            setState(() {
              _canWebViewGoBack = value;
            });
          });
          return NavigationDecision.navigate;
        },
      ))
      ..loadRequest(uri);
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvoked: (didPop) async {
        if (_canWebViewGoBack) {
          // WebView有历史页面时,执行返回操作
          await controller.goBack();
          // 返回后重新检查可返回状态
          final canGoBack = await controller.canGoBack();
          setState(() {
            _canWebViewGoBack = canGoBack;
          });
        } else {
          // WebView无历史页面时,触发双击关闭逻辑
          DoubleBackToCloseApp.of(context)?.onWillPop();
        }
      },
      child: Scaffold(
        floatingActionButton: Visibility(
          // 仅WebView可返回时显示返回按钮
          visible: _canWebViewGoBack,
          child: Container(
            height: 40.0,
            width: 40.0,
            child: FittedBox(
              child: FloatingActionButton(
                child: const Icon(Icons.arrow_back),
                onPressed: () async {
                  await controller.goBack();
                  final canGoBack = await controller.canGoBack();
                  setState(() {
                    _canWebViewGoBack = canGoBack;
                  });
                },
                backgroundColor: Colors.grey.shade200,
              ),
            ),
          ),
        ),
        body: SafeArea(
          child: DoubleBackToCloseApp(
            snackBar: const SnackBar(
              content: Text('再次点击返回键关闭应用'),
              duration: Duration(seconds: 2),
            ),
            child: WebViewWidget(controller: controller),
          ),
        ),
      ),
    );
  }
}

关键逻辑说明

  • WebView状态监听:通过controller.canGoBack()实时获取WebView是否有历史页面可返回,更新_canWebViewGoBack状态。
  • 返回键优先级:在onPopInvoked中先判断WebView是否可返回,优先处理页面返回;无历史页面时再触发双击关闭逻辑。
  • 体验优化:给浮动返回按钮添加Visibility控制,避免用户点击无效按钮。

内容的提问来源于stack exchange,提问作者gill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:25:23