我有一个 Flutter 新闻阅读器应用程序,其内容使用 WordPress JSON feed。我使用高级广告 Wordpress 插件,并将网络上的相同广告与帖子内容一起注入到 JSON Feed 中。
当我的 WebView 加载时,它会自动生成一个外部浏览器。这是没有用户交互的情况。广告在网络视图中加载良好。我在 YouTube 上遇到了同样的问题,但对 Google 广告网址应用相同的解决方案不起作用。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher.dart';
import 'data.dart'; // Post model
import 'html.dart'; // For building HTML content
import 'package:share_plus/share_plus.dart'; // Import share_plus
class PostDetailScreen extends StatefulWidget {
final Post post;
final List<Post> recentPosts;
const PostDetailScreen({Key? key, required this.post, required this.recentPosts}) : super(key: key);
@override
PostDetailScreenState createState() => PostDetailScreenState();
}
class PostDetailScreenState extends State<PostDetailScreen> {
late WebViewController _controller;
String htmlContent = '';
bool isLoading = true;
@override
void initState() {
super.initState();
loadContent();
}
Future<void> loadContent() async {
String encodedVisbyFont = await loadEncodedFont();
String encodedCanelaFont = await loadCanelaFont();
htmlContent = buildHtmlContent(
widget.post.imageUrl,
widget.post.title,
widget.post.content,
widget.post.author,
widget.post.modified,
encodedVisbyFont,
encodedCanelaFont,
widget.recentPosts.take(10).toList()
);
setState(() {
isLoading = false;
});
}
Future<void> updatePostContent(String postLink) async {
final selectedPost = widget.recentPosts.firstWhere(
(post) => post.link == postLink,
orElse: () => widget.post,
);
String updatedContent = buildHtmlContent(
selectedPost.imageUrl,
selectedPost.title,
selectedPost.content,
selectedPost.author,
selectedPost.modified,
await loadEncodedFont(),
await loadCanelaFont(),
widget.recentPosts.take(10).toList(),
);
setState(() {
htmlContent = updatedContent;
});
_controller.loadUrl(Uri.dataFromString(
htmlContent,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8'),
).toString());
}
@override
Widget build(BuildContext context) {
final bool tablet = MediaQuery.of(context).size.width > 600;
final double titleFontSize = tablet ? 36.0 : 24.0;
final double iconSize = tablet ? 36.0 : 30.0;
final EdgeInsetsGeometry iconPadding = tablet ? const EdgeInsets.all(12.0) : const EdgeInsets.all(8.0);
final double appBarHeight = tablet ? 70.0 : 56.0;
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(appBarHeight),
child: AppBar(
title: Text(
'FRENCHLY',
style: TextStyle(
fontFamily: 'Oswald',
fontSize: titleFontSize,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
backgroundColor: const Color(0xFF1D5986),
centerTitle: true,
iconTheme: IconThemeData(color: Colors.white, size: iconSize),
actions: <Widget>[
Padding(
padding: iconPadding,
child: IconButton(
icon: Icon(Icons.share, color: Colors.white, size: iconSize),
onPressed: () {
Share.share('${widget.post.title}\n\n${widget.post.link}');
},
),
),
],
),
),
body: isLoading
? const Center(child: CircularProgressIndicator())
: WebView(
initialUrl: Uri.dataFromString(
htmlContent,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8'),
).toString(),
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) {
_controller = controller;
},
navigationDelegate: (NavigationRequest request) async {
if (request.url.startsWith('post://')) {
final postLink = Uri.decodeFull(request.url.substring(7));
updatePostContent(postLink);
return NavigationDecision.prevent;
} else if (request.url.contains('youtube.com') || request.url.contains('youtu.be')) {
// Load YouTube URLs in the WebView itself
return NavigationDecision.navigate;
} else if (await canLaunchUrl(Uri.parse(request.url))) {
await launchUrl(Uri.parse(request.url), mode: LaunchMode.externalApplication);
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
);
}
}
这最终为我工作:
navigationDelegate: (NavigationRequest request) async {if (request.url.startsWith('post://')) {
final postLink = Uri.decodeFull(request.url.substring(7));
updatePostContent(postLink);
return NavigationDecision.prevent;
} else if (request.url.contains('youtube.com') || request.url.contains('youtu.be')) {
// Load YouTube URLs in the WebView itself
return NavigationDecision.navigate;
} else if (request.url.contains('googlesyndication.com')) {
// Load Google Ad URLs in the WebView itself
return NavigationDecision.navigate;
} else if (await canLaunchUrl(Uri.parse(request.url))) {
await launchUrl(Uri.parse(request.url), mode: `enter code here`LaunchMode.externalApplication);
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},