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

Flutter实现从本地HTML链接跳转至指定Dart页面的方法

Hey there! Got it, so you want to jump from your WebView's HTML link to Page_two.dart in Flutter. Let's get this sorted out step by step—your current setup loads the HTML fine, but we need to intercept the link click and route it to your Flutter page instead of letting the WebView try to load it as a URL.

First, change your HTML link to use a custom scheme (like myapp://) instead of directly referencing Page_two.dart. This makes it easy to intercept and distinguish from regular web URLs:

<p style="margin-left: 30px;">Read <a style="text-decoration: none;" href="myapp://open_prohibited_ads">Prohibited ads</a></p>

Step 2: Modify Page_one.dart (Using flutter_webview_plugin)

Since your current code uses WebviewScaffold from the flutter_webview_plugin package, we'll add a listener to catch the custom scheme link and trigger the Flutter navigation:

First, make sure you have the package imported, plus your Page_two.dart:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:your_app_name/Page_two.dart'; // Replace with your actual path

Then update your state class to include URL listening and navigation logic:

class LoadHTMLFileToWEbView extends StatefulWidget {
  @override
  _LoadHTMLFileToWEbViewState createState() => _LoadHTMLFileToWEbViewState();
}

class _LoadHTMLFileToWEbViewState extends State<LoadHTMLFileToWEbView> {
  final FlutterWebviewPlugin _webviewPlugin = FlutterWebviewPlugin();
  StreamSubscription<String>? _urlChangeSubscription;

  @override
  void initState() {
    super.initState();
    // Listen for URL changes in the WebView
    _urlChangeSubscription = _webviewPlugin.onUrlChanged.listen((String url) {
      // Check if the URL matches our custom scheme
      if (url.startsWith('myapp://open_prohibited_ads')) {
        // Navigate to Page_two.dart
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => Page_two()),
        );
        // Stop the WebView from trying to load this invalid URL
        _webviewPlugin.stopLoading();
      }
    });
  }

  @override
  void dispose() {
    // Clean up subscriptions to avoid memory leaks
    _urlChangeSubscription?.cancel();
    _webviewPlugin.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: _loadLocalHTML(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return WebviewScaffold(
            appBar: AppBar(title: Text("Load HTML file in WebView")),
            withJavascript: true,
            appCacheEnabled: true,
            url: Uri.dataFromString(
              snapshot.data!,
              mimeType: 'text/html',
              encoding: utf8,
            ).toString(),
          );
        } else if (snapshot.hasError) {
          return Scaffold(
            body: Center(
              child: Text("${snapshot.error}"),
            ),
          );
        }
        return const Scaffold(
          body: Center(child: CircularProgressIndicator()),
        );
      },
    );
  }

  Future<String> _loadLocalHTML() async {
    return await rootBundle.loadString('assets/test.html');
  }
}

If you're using the official webview_flutter package (version 4.x+), you can use the navigationDelegate to intercept requests directly, which is more streamlined:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:your_app_name/Page_two.dart';

class LoadHTMLFileToWEbView extends StatefulWidget {
  @override
  _LoadHTMLFileToWEbViewState createState() => _LoadHTMLFileToWEbViewState();
}

class _LoadHTMLFileToWEbViewState extends State<LoadHTMLFileToWEbView> {
  late WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: _loadLocalHTML(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Scaffold(
            appBar: AppBar(title: Text("Load HTML file in WebView")),
            body: WebView(
              initialUrl: Uri.dataFromString(
                snapshot.data!,
                mimeType: 'text/html',
                encoding: utf8,
              ).toString(),
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (controller) {
                _webViewController = controller;
              },
              navigationDelegate: (NavigationRequest request) {
                // Intercept the custom scheme link
                if (request.url.startsWith('myapp://open_prohibited_ads')) {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => Page_two()),
                  );
                  // Prevent WebView from loading the URL
                  return NavigationDecision.prevent;
                }
                // Allow all other navigation requests
                return NavigationDecision.navigate;
              },
            ),
          );
        } else if (snapshot.hasError) {
          return Scaffold(
            body: Center(
              child: Text("${snapshot.error}"),
            ),
          );
        }
        return const Scaffold(
          body: Center(child: CircularProgressIndicator()),
        );
      },
    );
  }

  Future<String> _loadLocalHTML() async {
    return await rootBundle.loadString('assets/test.html');
  }
}

Step 3: Make Sure Page_two.dart is Valid

Just a quick check—ensure your Page_two.dart is a proper Flutter widget, like this example:

import 'package:flutter/material.dart';

class Page_two extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Prohibited Ads")),
      body: const Center(
        child: Text("This is your Page Two content!"),
      ),
    );
  }
}

Key Notes

  • Using a custom scheme ensures we don't accidentally intercept regular web links.
  • Always clean up subscriptions/plugin instances in dispose() to avoid memory leaks.
  • The navigationDelegate in the official webview_flutter package is the modern, recommended approach for handling navigation intercepts.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:08:55