|
|
@@ -60,28 +60,28 @@ class WebView extends BaseView<WebController> {
|
|
|
}
|
|
|
|
|
|
Widget _buildWebContent() {
|
|
|
- return Obx(() {
|
|
|
- // 使用响应式状态栏样式
|
|
|
- final statusBarStyle = controller.currentStatusBarStyle.value;
|
|
|
-
|
|
|
- return AnnotatedRegion<SystemUiOverlayStyle>(
|
|
|
- value: statusBarStyle,
|
|
|
+ // 将 WebView 移出 Obx,避免重复创建
|
|
|
+ return Obx(
|
|
|
+ () => AnnotatedRegion<SystemUiOverlayStyle>(
|
|
|
+ value: controller.currentStatusBarStyle.value,
|
|
|
child: Stack(
|
|
|
children: [
|
|
|
InAppWebView(
|
|
|
+ key: const ValueKey('nomo_webview'), // 添加唯一 key
|
|
|
initialUrlRequest: URLRequest(url: WebUri(controller.url)),
|
|
|
-
|
|
|
initialSettings: InAppWebViewSettings(
|
|
|
userAgent: controller.userAgent,
|
|
|
javaScriptEnabled: true,
|
|
|
useShouldOverrideUrlLoading: true,
|
|
|
- useOnLoadResource: true,
|
|
|
mediaPlaybackRequiresUserGesture: false,
|
|
|
allowsInlineMediaPlayback: true,
|
|
|
- iframeAllow: "camera; microphone",
|
|
|
- iframeAllowFullscreen: true,
|
|
|
allowFileAccessFromFileURLs: true,
|
|
|
allowUniversalAccessFromFileURLs: true,
|
|
|
+ // iOS 特定设置
|
|
|
+ allowsBackForwardNavigationGestures: true,
|
|
|
+ suppressesIncrementalRendering: false,
|
|
|
+ transparentBackground: false,
|
|
|
+ isInspectable: true,
|
|
|
),
|
|
|
onWebViewCreated:
|
|
|
(InAppWebViewController webViewController) async {
|
|
|
@@ -125,9 +125,22 @@ class WebView extends BaseView<WebController> {
|
|
|
) async {
|
|
|
final url = navigationAction.request.url?.toString() ?? '';
|
|
|
|
|
|
+ // 如果是空 URL 或本地资源,允许加载
|
|
|
+ if (url.isEmpty ||
|
|
|
+ url.startsWith('assets/') ||
|
|
|
+ url.startsWith('file://') ||
|
|
|
+ url.startsWith('about:')) {
|
|
|
+ return NavigationActionPolicy.ALLOW;
|
|
|
+ }
|
|
|
+
|
|
|
try {
|
|
|
final uri = Uri.parse(url);
|
|
|
|
|
|
+ // 处理 http/https 链接 - 允许在 WebView 中加载
|
|
|
+ if (uri.scheme == 'http' || uri.scheme == 'https') {
|
|
|
+ return NavigationActionPolicy.ALLOW;
|
|
|
+ }
|
|
|
+
|
|
|
// 处理 intent:// 链接
|
|
|
if (url.startsWith("intent://")) {
|
|
|
final parsedUrl = controller.parseIntentUrl(url);
|
|
|
@@ -148,8 +161,9 @@ class WebView extends BaseView<WebController> {
|
|
|
}
|
|
|
return NavigationActionPolicy.CANCEL;
|
|
|
}
|
|
|
+
|
|
|
// 处理下载链接
|
|
|
- else if (uri.path.endsWith(".apk") ||
|
|
|
+ if (uri.path.endsWith(".apk") ||
|
|
|
uri.path.endsWith(".pdf") ||
|
|
|
uri.path.contains("download")) {
|
|
|
if (await canLaunchUrl(uri)) {
|
|
|
@@ -161,25 +175,29 @@ class WebView extends BaseView<WebController> {
|
|
|
return NavigationActionPolicy.CANCEL;
|
|
|
}
|
|
|
|
|
|
- // 处理 http/https 链接
|
|
|
- if (uri.scheme == 'http' || uri.scheme == 'https') {
|
|
|
- return NavigationActionPolicy.ALLOW;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理其他 scheme
|
|
|
- if (await canLaunchUrl(uri)) {
|
|
|
- await launchUrl(
|
|
|
- uri,
|
|
|
- mode: LaunchMode.externalApplication,
|
|
|
- );
|
|
|
+ // 处理其他自定义 scheme(如 tel:, mailto:, weixin: 等)
|
|
|
+ if (uri.scheme != 'http' &&
|
|
|
+ uri.scheme != 'https' &&
|
|
|
+ uri.scheme != 'file' &&
|
|
|
+ uri.scheme != 'about') {
|
|
|
+ if (await canLaunchUrl(uri)) {
|
|
|
+ await launchUrl(
|
|
|
+ uri,
|
|
|
+ mode: LaunchMode.externalApplication,
|
|
|
+ );
|
|
|
+ return NavigationActionPolicy.CANCEL;
|
|
|
+ }
|
|
|
}
|
|
|
} catch (e) {
|
|
|
log("Error handling shouldOverrideUrlLoading: $e");
|
|
|
}
|
|
|
|
|
|
- return NavigationActionPolicy.CANCEL;
|
|
|
+ // 默认允许加载
|
|
|
+ return NavigationActionPolicy.ALLOW;
|
|
|
},
|
|
|
),
|
|
|
+
|
|
|
+ // 加载进度条
|
|
|
Obx(
|
|
|
() => controller.isLoading.value
|
|
|
? LinearProgressIndicator(
|
|
|
@@ -195,7 +213,7 @@ class WebView extends BaseView<WebController> {
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
- );
|
|
|
- });
|
|
|
+ ),
|
|
|
+ );
|
|
|
}
|
|
|
}
|