6.6.3 - Alpha5 - webview 元素支持基于 JsBridge 的 Web 页面布局 (Ref to Auto.js Pro) (issue #281)
This commit is contained in:
93
app/src/main/assets-app/sample/布局/Vue2 + Vant (SFC)/main.js
Normal file
93
app/src/main/assets-app/sample/布局/Vue2 + Vant (SFC)/main.js
Normal file
@@ -0,0 +1,93 @@
|
||||
'ui';
|
||||
|
||||
ui.layout(
|
||||
<vertical>
|
||||
<webview id="web" url="web/index.html" w="*" h="*"/>
|
||||
</vertical>,
|
||||
);
|
||||
|
||||
ui.statusBarColor('#ffffff');
|
||||
|
||||
let FILE_REQ_CODE = 11525;
|
||||
let fileChooserResolve = null;
|
||||
let web = ui['web'];
|
||||
|
||||
// 监听 WebView 的控制台消息, 打印到控制台
|
||||
web.events.on('console_message', (event, msg) => {
|
||||
console.log(`${files.getName(msg.sourceId())}:${msg.lineNumber()}: ${msg.message()}`);
|
||||
});
|
||||
|
||||
// 处理来自 Web 的请求
|
||||
web.jsBridge
|
||||
// 处理读取本地文件的请求
|
||||
.handle('fetch', (event, args) => {
|
||||
return files.read(files.join(files.path('web'), args.path));
|
||||
})
|
||||
// 处理显示日志界面的请求
|
||||
.handle('show-log', (event) => {
|
||||
app.startActivity('console');
|
||||
})
|
||||
// 处理 toastLog 消息
|
||||
.handle('toast-log', (event, msg) => {
|
||||
toastLog(msg);
|
||||
})
|
||||
// 处理设置无障碍服务的请求
|
||||
.handle('set-accessibility-enabled', (event, enabled) => {
|
||||
enabled ? auto.enable() : auto.disable();
|
||||
})
|
||||
// 处理获取无障碍服务状态的请求
|
||||
.handle('get-accessibility-enabled', (event) => {
|
||||
return auto.isRunning();
|
||||
})
|
||||
// 处理获取应用版本名称的请求
|
||||
.handle('get-app-version-name', (event) => {
|
||||
return app.autojs.versionName;
|
||||
})
|
||||
// 处理文件选择的请求
|
||||
.handle('select-file', (event, mimeType) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (fileChooserResolve) {
|
||||
toastLog('File chooser is already open.');
|
||||
return;
|
||||
}
|
||||
fileChooserResolve = resolve;
|
||||
|
||||
let intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType(mimeType);
|
||||
intent.addCategory(android.content.Intent.CATEGORY_OPENABLE);
|
||||
activity.startActivityForResult(intent, FILE_REQ_CODE);
|
||||
});
|
||||
|
||||
})
|
||||
// 处理显示设备信息的请求
|
||||
.handle('show-device-info-dialog', (event) => {
|
||||
new MaterialDialog.Builder(activity)
|
||||
.title(R.strings.text_app_and_device_info)
|
||||
.content(DeviceUtils.getDeviceSummaryWithSimpleAppInfo(activity))
|
||||
.neutralText(R.strings.dialog_button_copy)
|
||||
.onNeutral((dialog, which) => {
|
||||
setClip(dialog.contentView.text);
|
||||
toast(activity.getString(R.strings.text_already_copied_to_clip));
|
||||
})
|
||||
.neutralColorRes(R.color.dialog_button_hint)
|
||||
.negativeText(R.strings.dialog_button_dismiss)
|
||||
.build()
|
||||
.show();
|
||||
})
|
||||
// 处理打开链接的请求. 这里用广播方式, 也可以使用 handle 的 "请求-响应" 方式
|
||||
.on('open-url', (event, url) => {
|
||||
app.openUrl(url);
|
||||
});
|
||||
|
||||
ui.emitter.on('activity_result', (requestCode, resultCode, data) => {
|
||||
if (requestCode === FILE_REQ_CODE && fileChooserResolve) {
|
||||
if (resultCode === android.app.Activity.RESULT_OK && data) {
|
||||
let uri = data.getData();
|
||||
let path = IntentUtils.getFileName(activity, uri);
|
||||
fileChooserResolve(path);
|
||||
} else {
|
||||
fileChooserResolve(null);
|
||||
}
|
||||
fileChooserResolve = null;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"assets": [],
|
||||
"useFeatures": [],
|
||||
"launchConfig": {
|
||||
"displaySplash": true,
|
||||
"hideLogs": true,
|
||||
"splashText": "Powered by AutoJs6",
|
||||
"stableMode": false
|
||||
},
|
||||
"main": "main.js",
|
||||
"name": "Vue2 + Vant (SFC)",
|
||||
"packageName": "org.example.vue2_vant",
|
||||
"scripts": {},
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0"
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<html>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<link rel="stylesheet" href="https://unpkg.com/vant@2.12/lib/index.css"/>
|
||||
|
||||
<script src="https://unpkg.com/vue@2.6/dist/vue.min.js"></script>
|
||||
<script src="https://unpkg.com/vue3-sfc-loader@0.8.4/dist/vue2-sfc-loader.js"></script>
|
||||
<script src="https://unpkg.com/vant@2.12/lib/vant.min.js"></script>
|
||||
<script src="autojs://sdk/v1.js"></script>
|
||||
<script>
|
||||
let { loadModule, vueVersion } = window['vue2-sfc-loader'];
|
||||
let options = {
|
||||
moduleCache: {
|
||||
vue: Vue,
|
||||
myData: {
|
||||
vueVersion,
|
||||
},
|
||||
},
|
||||
async getFile(url) {
|
||||
let getContentData;
|
||||
if (typeof $autojs !== 'undefined') {
|
||||
let res = await $autojs.invoke('fetch', { path: url });
|
||||
getContentData = (asBinary) => asBinary ? str2ab(res) : res;
|
||||
} else {
|
||||
let res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
throw Object.assign(new Error(res.statusText + ' ' + url), { res });
|
||||
}
|
||||
getContentData = (asBinary) => asBinary ? res.arrayBuffer() : res.text();
|
||||
}
|
||||
return {
|
||||
getContentData,
|
||||
};
|
||||
|
||||
function str2ab(str) {
|
||||
let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
|
||||
let bufView = new Uint16Array(buf);
|
||||
for (let i = 0, strLen = str.length; i < strLen; i++) {
|
||||
bufView[i] = str.charCodeAt(i);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
},
|
||||
addStyle() {
|
||||
/* unused here */
|
||||
},
|
||||
};
|
||||
|
||||
loadModule('/main.vue', options)
|
||||
.then(component => new Vue(component).$mount('#app'));
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
127
app/src/main/assets-app/sample/布局/Vue2 + Vant (SFC)/web/main.vue
Normal file
127
app/src/main/assets-app/sample/布局/Vue2 + Vant (SFC)/web/main.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<van-row>
|
||||
<van-nav-bar title="基于 Vue 的界面"/>
|
||||
|
||||
<van-tabs v-model="activeTab">
|
||||
<van-tab title="配置">
|
||||
<van-cell-group title="权限">
|
||||
<van-cell title="无障碍服务" label="用于脚本自动操作 (点击/长按/滑动等)">
|
||||
<van-switch
|
||||
v-model="accessibilityServiceEnabled"
|
||||
@input="onAccessibilityServiceCheckChanged"
|
||||
/>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="配置">
|
||||
<van-cell title="开关样本">
|
||||
<van-switch
|
||||
v-model="sampleSwitchChecked"
|
||||
@change="onSampleSwitchChanged"
|
||||
/>
|
||||
</van-cell>
|
||||
<van-field v-model="greeting"
|
||||
label="问候语"
|
||||
placeholder="请输入问候语"
|
||||
maxLength="20"
|
||||
input-align="right"
|
||||
/>
|
||||
<van-field v-model.number="count"
|
||||
label="运行次数"
|
||||
placeholder="请输入运行次数"
|
||||
maxLength="4"
|
||||
inputmode="numeric"
|
||||
input-align="right"
|
||||
/>
|
||||
<van-field
|
||||
label="选择文件"
|
||||
:value="selectedFilePath"
|
||||
placeholder="选择一个文件"
|
||||
readonly
|
||||
clickable
|
||||
@click.native="selectFile"
|
||||
input-align="right"
|
||||
/>
|
||||
</van-cell-group>
|
||||
</van-tab>
|
||||
|
||||
<van-tab title="运行">
|
||||
<van-cell title="查看日志" is-link @click="showLog"/>
|
||||
<van-row type="flex" justify="center">
|
||||
<van-button type="primary" @click="run" style="margin-top: 12px;">运行</van-button>
|
||||
</van-row>
|
||||
</van-tab>
|
||||
|
||||
<van-tab title="关于">
|
||||
<van-cell
|
||||
value="运行环境"
|
||||
:title="appVersionName ? `AutoJs6 ${appVersionName}` : `AutoJs6`"
|
||||
label="WebView + Android"
|
||||
@click="showDeviceInfoDialog"
|
||||
/>
|
||||
<van-cell
|
||||
title="Vue.js 2.6"
|
||||
label="渐进式 JavaScript 框架"
|
||||
is-link
|
||||
@click="openVueWebsite"
|
||||
/>
|
||||
<van-cell
|
||||
title="Vant 2.12"
|
||||
label="轻量, 可靠的移动端 Vue 组件库"
|
||||
is-link
|
||||
@click="openVantWebsite"
|
||||
/>
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
</van-row>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
accessibilityServiceEnabled: false,
|
||||
activeTab: 0,
|
||||
sampleSwitchChecked: true,
|
||||
greeting: 'Hello',
|
||||
count: 192,
|
||||
appVersionName: '',
|
||||
selectedFilePath: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
$autojs.invoke('get-accessibility-enabled').then((value) => {
|
||||
this.accessibilityServiceEnabled = value;
|
||||
});
|
||||
$autojs.invoke('get-app-version-name').then((value) => {
|
||||
this.appVersionName = value;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onAccessibilityServiceCheckChanged(checked) {
|
||||
$autojs.invoke('set-accessibility-enabled', checked);
|
||||
},
|
||||
onSampleSwitchChanged(checked) {
|
||||
$autojs.invoke('toast-log', `样本开关已${checked ? '开启' : '关闭'}`);
|
||||
},
|
||||
showLog() {
|
||||
$autojs.invoke('show-log');
|
||||
},
|
||||
openVantWebsite() {
|
||||
$autojs.send('open-url', 'https://vant-ui.github.io/vant/v2/#/zh-CN/');
|
||||
},
|
||||
openVueWebsite() {
|
||||
$autojs.send('open-url', 'https://cn.vuejs.org/');
|
||||
},
|
||||
run() {
|
||||
$autojs.invoke('toast-log', `greeting: "${this.greeting}"\ncount: ${this.count}`);
|
||||
},
|
||||
selectFile() {
|
||||
$autojs.invoke('select-file', '*/*').then((path) => {
|
||||
this.selectedFilePath = path || '';
|
||||
});
|
||||
},
|
||||
showDeviceInfoDialog() {
|
||||
$autojs.invoke('show-device-info-dialog');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
17
app/src/main/assets-app/sample/布局/可交互 HTML/index.html
Normal file
17
app/src/main/assets-app/sample/布局/可交互 HTML/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Interactive HTML</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<link rel="stylesheet" href="style.css"/>
|
||||
<script src="autojs://sdk/v1.js"></script>
|
||||
<script src="index.js"></script>
|
||||
<button id="testButton">点击测试</button>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
10
app/src/main/assets-app/sample/布局/可交互 HTML/index.js
Normal file
10
app/src/main/assets-app/sample/布局/可交互 HTML/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const winOnloadBak = window.onload ? window.onload.bind(window) : null;
|
||||
|
||||
window.onload = function () {
|
||||
if (typeof winOnloadBak === 'function') {
|
||||
winOnloadBak();
|
||||
}
|
||||
document.getElementById('testButton').addEventListener('click', () => {
|
||||
$autojs.invoke('toast-log', '按钮已被点击');
|
||||
});
|
||||
};
|
||||
13
app/src/main/assets-app/sample/布局/可交互 HTML/main.js
Normal file
13
app/src/main/assets-app/sample/布局/可交互 HTML/main.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'ui';
|
||||
|
||||
ui.layout(
|
||||
<vertical>
|
||||
<webview id="web" url="index.html" w="*" h="*"/>
|
||||
</vertical>,
|
||||
);
|
||||
|
||||
let web = ui['web'];
|
||||
|
||||
web.jsBridge.handle('toast-log', (event, msg) => {
|
||||
toastLog(msg);
|
||||
});
|
||||
16
app/src/main/assets-app/sample/布局/可交互 HTML/project.json
Normal file
16
app/src/main/assets-app/sample/布局/可交互 HTML/project.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"assets": [],
|
||||
"useFeatures": [],
|
||||
"launchConfig": {
|
||||
"displaySplash": true,
|
||||
"hideLogs": true,
|
||||
"splashText": "Powered by AutoJs6",
|
||||
"stableMode": false
|
||||
},
|
||||
"main": "main.js",
|
||||
"name": "可交互 HTML",
|
||||
"packageName": "org.example.interactive_html",
|
||||
"scripts": {},
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0"
|
||||
}
|
||||
25
app/src/main/assets-app/sample/布局/可交互 HTML/style.css
Normal file
25
app/src/main/assets-app/sample/布局/可交互 HTML/style.css
Normal file
@@ -0,0 +1,25 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
#testButton {
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #006400;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#testButton:hover {
|
||||
background-color: #008000;
|
||||
}
|
||||
Reference in New Issue
Block a user