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.
Step 1: Update Your HTML Link
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'); } }
Alternative: Using Official webview_flutter Package (Recommended)
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
navigationDelegatein the officialwebview_flutterpackage is the modern, recommended approach for handling navigation intercepts.
内容的提问来源于stack exchange,提问作者H Zan

