|
@@ -16,19 +16,14 @@ class WebViewXPage extends StatefulWidget {
|
|
|
|
|
|
class _WebViewXPageState extends State<WebViewXPage> {
|
|
|
late WebViewXController webviewController;
|
|
|
- final executeJsErrorMessage =
|
|
|
- 'Failed to execute this script, please check your code. Continue to use the app without this script.';
|
|
|
- final javaScriptsFromAssets = [];
|
|
|
- Size get screenSize => MediaQuery.of(context).size;
|
|
|
+ final executeJsErrorMessage = '脚本执行失败,请检查代码是否正确嵌入';
|
|
|
|
|
|
- Future<String> _loadJSFromAssets(String path) {
|
|
|
- return rootBundle.loadString(path);
|
|
|
- }
|
|
|
+
|
|
|
+ List<String> scriptsFromAssets = [];
|
|
|
+ Size get screenSize => MediaQuery.of(context).size;
|
|
|
|
|
|
- @override
|
|
|
- void initState() {
|
|
|
-
|
|
|
- super.initState();
|
|
|
+
|
|
|
+ Future<String> _preloadJS() async {
|
|
|
final scriptsList = [
|
|
|
"threejsview/js/build/three.js",
|
|
|
"threejsview/js/build/THREE.MeshLine.js",
|
|
@@ -56,9 +51,17 @@ class _WebViewXPageState extends State<WebViewXPage> {
|
|
|
"threejsview/js/customScript/utility/OSHelper.js",
|
|
|
];
|
|
|
for (String path in scriptsList) {
|
|
|
- _loadJSFromAssets(path).then((value) {
|
|
|
- javaScriptsFromAssets.add(value);
|
|
|
- });
|
|
|
+ var value = await _loadJSFromAssets(path);
|
|
|
+ scriptsFromAssets.add(value);
|
|
|
+ }
|
|
|
+ return Future.value("");
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<String> _loadJSFromAssets(String path) async {
|
|
|
+ try {
|
|
|
+ return await rootBundle.loadString(path);
|
|
|
+ } catch (e) {
|
|
|
+ return Future.error(e);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -122,149 +125,45 @@ class _WebViewXPageState extends State<WebViewXPage> {
|
|
|
}
|
|
|
|
|
|
Widget _buildWebViewX() {
|
|
|
- return WebViewX(
|
|
|
- key: const ValueKey('webviewx'),
|
|
|
- initialContent: "<h2> Hello webviewX ! <h2>",
|
|
|
- initialSourceType: SourceType.html,
|
|
|
- height: screenSize.height / 1.5,
|
|
|
- width: min(screenSize.width * 0.8, 1024),
|
|
|
- onWebViewCreated: (controller) => webviewController = controller,
|
|
|
- onPageStarted: (src) => debugPrint('A new page has started loading'),
|
|
|
- onPageFinished: (src) => debugPrint('The page has finished loading'),
|
|
|
- jsContent:
|
|
|
- javaScriptsFromAssets.map((e) => EmbeddedJsContent(js: e)).toSet(),
|
|
|
- dartCallBacks: {
|
|
|
- DartCallback(
|
|
|
- name: 'TestDartCallback',
|
|
|
- callBack: (msg) => showSnackBar(msg.toString(), context),
|
|
|
- )
|
|
|
- },
|
|
|
- webSpecificParams: const WebSpecificParams(
|
|
|
- printDebugInfo: true,
|
|
|
- ),
|
|
|
- mobileSpecificParams: const MobileSpecificParams(
|
|
|
- androidEnableHybridComposition: true,
|
|
|
- ),
|
|
|
- navigationDelegate: (navigation) {
|
|
|
- debugPrint(navigation.content.sourceType.toString());
|
|
|
- return NavigationDecision.navigate;
|
|
|
- },
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- void _setUrl() {
|
|
|
- webviewController.loadContent(
|
|
|
- 'https://flutter.dev',
|
|
|
- SourceType.url,
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- void _setUrlBypass() {
|
|
|
- webviewController.loadContent(
|
|
|
- 'https://www.baidu.com/',
|
|
|
- SourceType.urlBypass,
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- void _setHtmlFromAssets() {
|
|
|
- webviewController.loadContent(
|
|
|
- 'threejsview/MainPage.html',
|
|
|
- SourceType.html,
|
|
|
- fromAssets: true,
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> _goForward() async {
|
|
|
- if (await webviewController.canGoForward()) {
|
|
|
- await webviewController.goForward();
|
|
|
- showSnackBar('Did go forward', context);
|
|
|
- } else {
|
|
|
- showSnackBar('Cannot go forward', context);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> _goBack() async {
|
|
|
- if (await webviewController.canGoBack()) {
|
|
|
- await webviewController.goBack();
|
|
|
- showSnackBar('Did go back', context);
|
|
|
- } else {
|
|
|
- showSnackBar('Cannot go back', context);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void _reload() {
|
|
|
- webviewController.reload();
|
|
|
- }
|
|
|
-
|
|
|
- void _toggleIgnore() {
|
|
|
- final ignoring = webviewController.ignoresAllGestures;
|
|
|
- webviewController.setIgnoreAllGestures(!ignoring);
|
|
|
- showSnackBar('Ignore events = ${!ignoring}', context);
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> _evalRawJsInGlobalContext() async {
|
|
|
- try {
|
|
|
- final result = await webviewController.evalRawJavascript(
|
|
|
- '2+2',
|
|
|
- inGlobalContext: true,
|
|
|
- );
|
|
|
- showSnackBar('The result is $result', context);
|
|
|
- } catch (e) {
|
|
|
- showAlertDialog(
|
|
|
- executeJsErrorMessage,
|
|
|
- context,
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> _callPlatformIndependentJsMethod() async {
|
|
|
- try {
|
|
|
- await webviewController.callJsMethod('testPlatformIndependentMethod', []);
|
|
|
- } catch (e) {
|
|
|
- showAlertDialog(
|
|
|
- executeJsErrorMessage,
|
|
|
- context,
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> _callPlatformSpecificJsMethod() async {
|
|
|
- try {
|
|
|
- await webviewController
|
|
|
- .callJsMethod('testPlatformSpecificMethod', ['Hi']);
|
|
|
- } catch (e) {
|
|
|
- showAlertDialog(
|
|
|
- executeJsErrorMessage,
|
|
|
- context,
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Future<void> _getWebviewContent() async {
|
|
|
- try {
|
|
|
- final content = await webviewController.getContent();
|
|
|
- showAlertDialog(content.source, context);
|
|
|
- } catch (e) {
|
|
|
- showAlertDialog('Failed to execute this task.', context);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Widget buildSpace({
|
|
|
- Axis direction = Axis.horizontal,
|
|
|
- double amount = 0.2,
|
|
|
- bool flex = true,
|
|
|
- }) {
|
|
|
- return flex
|
|
|
- ? Flexible(
|
|
|
- child: FractionallySizedBox(
|
|
|
- widthFactor: direction == Axis.horizontal ? amount : null,
|
|
|
- heightFactor: direction == Axis.vertical ? amount : null,
|
|
|
- ),
|
|
|
- )
|
|
|
- : SizedBox(
|
|
|
- width: direction == Axis.horizontal ? amount : null,
|
|
|
- height: direction == Axis.vertical ? amount : null,
|
|
|
- );
|
|
|
+ return FutureBuilder<String>(
|
|
|
+ future: _preloadJS(),
|
|
|
+ builder: (context, AsyncSnapshot<String> snapshot) {
|
|
|
+ if (snapshot.hasData) {
|
|
|
+ return WebViewX(
|
|
|
+ key: const ValueKey('webviewx'),
|
|
|
+ initialContent: "<h2> Hello webviewX ! <h2>",
|
|
|
+ initialSourceType: SourceType.html,
|
|
|
+ height: screenSize.height / 1.5,
|
|
|
+ width: min(screenSize.width * 0.8, 1024),
|
|
|
+ onWebViewCreated: (controller) => webviewController = controller,
|
|
|
+ onPageStarted: (src) =>
|
|
|
+ debugPrint('A new page has started loading'),
|
|
|
+ onPageFinished: (src) =>
|
|
|
+ debugPrint('The page has finished loading'),
|
|
|
+ jsContent: scriptsFromAssets
|
|
|
+ .map((e) => EmbeddedJsContent(js: e))
|
|
|
+ .toSet(),
|
|
|
+ dartCallBacks: {
|
|
|
+ DartCallback(
|
|
|
+ name: 'TestDartCallback',
|
|
|
+ callBack: (msg) => showSnackBar(msg.toString(), context),
|
|
|
+ )
|
|
|
+ },
|
|
|
+ webSpecificParams: const WebSpecificParams(
|
|
|
+ printDebugInfo: true,
|
|
|
+ ),
|
|
|
+ mobileSpecificParams: const MobileSpecificParams(
|
|
|
+ androidEnableHybridComposition: true,
|
|
|
+ ),
|
|
|
+ navigationDelegate: (navigation) {
|
|
|
+ debugPrint(navigation.content.sourceType.toString());
|
|
|
+ return NavigationDecision.navigate;
|
|
|
+ },
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return const CircularProgressIndicator();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
List<Widget> _buildButtons() {
|
|
@@ -296,21 +195,6 @@ class _WebViewXPageState extends State<WebViewXPage> {
|
|
|
onTap: _evalRawJsInGlobalContext,
|
|
|
),
|
|
|
buildSpace(direction: Axis.vertical, flex: false, amount: 20.0),
|
|
|
- createButton(
|
|
|
- text: '测试与平台无关的 JS 代码 (console.log)',
|
|
|
- onTap: _callPlatformIndependentJsMethod,
|
|
|
- ),
|
|
|
- buildSpace(direction: Axis.vertical, flex: false, amount: 20.0),
|
|
|
- createButton(
|
|
|
- text: '调用区分平台的 JS 方法,结果会返回到 flutter 方法',
|
|
|
- onTap: _callPlatformSpecificJsMethod,
|
|
|
- ),
|
|
|
- buildSpace(direction: Axis.vertical, flex: false, amount: 20.0),
|
|
|
- createButton(
|
|
|
- text: '返回当前 webview 内容',
|
|
|
- onTap: _getWebviewContent,
|
|
|
- ),
|
|
|
- buildSpace(direction: Axis.vertical, flex: false, amount: 20.0),
|
|
|
const Text(
|
|
|
"👇👇 Threejs 页面相关(建议顺序执行) 👇👇",
|
|
|
style: TextStyle(fontSize: 20),
|
|
@@ -372,4 +256,82 @@ class _WebViewXPageState extends State<WebViewXPage> {
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ void _setUrlBypass() {
|
|
|
+ webviewController.loadContent(
|
|
|
+ 'https://www.baidu.com/',
|
|
|
+ SourceType.urlBypass,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ void _setHtmlFromAssets() {
|
|
|
+ webviewController.loadContent(
|
|
|
+ 'threejsview/MainPage.html',
|
|
|
+ SourceType.html,
|
|
|
+ fromAssets: true,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<void> _goForward() async {
|
|
|
+ if (await webviewController.canGoForward()) {
|
|
|
+ await webviewController.goForward();
|
|
|
+ showSnackBar('Did go forward', context);
|
|
|
+ } else {
|
|
|
+ showSnackBar('Cannot go forward', context);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<void> _goBack() async {
|
|
|
+ if (await webviewController.canGoBack()) {
|
|
|
+ await webviewController.goBack();
|
|
|
+ showSnackBar('Did go back', context);
|
|
|
+ } else {
|
|
|
+ showSnackBar('Cannot go back', context);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void _reload() {
|
|
|
+ webviewController.reload();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ void _toggleIgnore() {
|
|
|
+ final ignoring = webviewController.ignoresAllGestures;
|
|
|
+ webviewController.setIgnoreAllGestures(!ignoring);
|
|
|
+ showSnackBar('Ignore events = ${!ignoring}', context);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Future<void> _evalRawJsInGlobalContext() async {
|
|
|
+ try {
|
|
|
+ final result = await webviewController.evalRawJavascript(
|
|
|
+ '2+2',
|
|
|
+ inGlobalContext: true,
|
|
|
+ );
|
|
|
+ showSnackBar('The result is $result', context);
|
|
|
+ } catch (e) {
|
|
|
+ showAlertDialog(
|
|
|
+ executeJsErrorMessage,
|
|
|
+ context,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget buildSpace({
|
|
|
+ Axis direction = Axis.horizontal,
|
|
|
+ double amount = 0.2,
|
|
|
+ bool flex = true,
|
|
|
+ }) {
|
|
|
+ return flex
|
|
|
+ ? Flexible(
|
|
|
+ child: FractionallySizedBox(
|
|
|
+ widthFactor: direction == Axis.horizontal ? amount : null,
|
|
|
+ heightFactor: direction == Axis.vertical ? amount : null,
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ : SizedBox(
|
|
|
+ width: direction == Axis.horizontal ? amount : null,
|
|
|
+ height: direction == Axis.vertical ? amount : null,
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|