link_cubit.dart
3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import 'dart:convert';
import 'package:appframe/config/routes.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:webview_flutter/webview_flutter.dart';
class LinkState extends Equatable {
final bool loaded;
final String url;
final String title;
final int screenType; // 1: 竖屏, 2: 横屏
const LinkState({
this.loaded = false,
this.url = '',
this.title = '',
this.screenType = 1,
});
LinkState copyWith({
bool? loaded,
String? url,
String? title,
int? screenType,
}) {
return LinkState(
loaded: loaded ?? this.loaded,
url: url ?? this.url,
title: title ?? this.title,
screenType: screenType ?? this.screenType,
);
}
@override
List<Object?> get props => [
loaded,
url,
title,
screenType,
];
}
class LinkCubit extends Cubit<LinkState> {
late final WebViewController _controller;
String? msg;
WebViewController get controller => _controller;
LinkCubit(super.initialState) {
if (state.screenType != 1) {
_setOrientation(2);
}
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
NavigationDelegate(
onUrlChange: (UrlChange url) {},
onPageStarted: (String url) {},
onPageFinished: (String url) async {
_controller.runJavaScript(
'document.querySelector("meta[name=viewport]").setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")',
);
// 如果 state.title 为空,则读取网页的 title
if (state.title.isEmpty) {
final pageTitle = await _controller.runJavaScriptReturningResult('document.title') as String?;
// 移除可能存在的引号
final cleanTitle = pageTitle?.replaceAll('"', '');
emit(state.copyWith(title: cleanTitle ?? ''));
}
_finishLoading();
},
),
)
..addJavaScriptChannel("xeJsBridge", onMessageReceived: (JavaScriptMessage message) {})
..loadRequest(Uri.parse(state.url));
}
void _onMessageReceived(JavaScriptMessage message) async {
// try {
// _dispatcher.dispatch(message.message, (response) {
// _sendResponse(response);
// }, webCubit: this);
// } catch (e) {
// debugPrint('消息解析错误: $e');
// }
}
// 向H5发送响应
void _sendResponse(Map<String, dynamic> response) {
String jsonString = jsonEncode(response);
String escapedJson = jsonString.replaceAll('"', '\\"');
final String script = 'xeJsBridgeCallback("$escapedJson");';
_controller.runJavaScript(script);
}
void _finishLoading() {
emit(state.copyWith(loaded: true));
}
// 设置屏幕方向
void _setOrientation(int screenType) {
if (screenType == 2) {
// 横屏模式
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
// 隐藏状态栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
} else {
// 竖屏模式(默认)
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
// 显示状态栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
}
}
Future<void> handleBack() async {
if (await _controller.canGoBack()) {
_controller.goBack();
} else {
router.pop(msg);
}
}
@override
Future<void> close() {
// 恢复为竖屏模式
if (state.screenType != 1) {
_setOrientation(1);
}
return super.close();
}
}