一、介绍
1.项目准备
- 工具:HBuilderX
- 搭建:html5plus + mui
2.项目创建及运行
- 创建:新建->新建5+App项目->输入文件名->创建
- 运行:运行->运行到手机或模拟器->运行到Android App基座->打包到手机
3.mui介绍
- 官网:mui:MUI基于原生HTML/CSS/JS,专为 5+App(纯混合开发)设计
- 作用:最接近原生APP体验的高性能前端框架
- 快捷键(html和js快捷键):文档->代码块->HBuilderX输入(如:mhe:标题栏)
4.html5plus
- 官网:html5plus
- 作用:提供访问设备原生API(如摄像头、蓝牙)的能力,但需依赖WebView容器
二、项目主要功能代码
1.tabbar功能
let pages = ['weixin.html', 'contact.html', 'find.html', 'my.html'];
mui.plusReady(function() {
/* 1.获取当前窗口的WebviewObject对象 */
let ws = plus.webview.currentWebview();
for (var i = 0; i < pages.length; i++) {
/* 2.创建新的Webview窗口 */
let wv = plus.webview.create(pages[i], pages[i], {
top: '0px',
bottom: '56px'
}, {});
/* 3.隐藏Webview窗口 */
wv.hide();
/* 4.在Webview窗口中添加子窗口 */
ws.append(wv);
}
/* 5.显示Webview窗口 */
plus.webview.show(pages[0]);
mui('.mui-bar-tab').on('tap', 'a', function(){
var href = this.getAttribute('href');
/* 5.显示Webview窗口 */
plus.webview.show(href);
})
})
2.页面跳转及传值
// 页面跳转及传值
mui.plusReady(function() {
mui('#scan').on('tap', 'a', function() {
mui.openWindow({
url: 'scan.html',
id: 'scan.html',
extras: {
title: '扫一扫页面'
}
})
})
})
// scan.html获取值
mui.plusReady(function () {
var ws=plus.webview.currentWebview();
mui('#scan-title')[0].innerText = ws.title || '页面';
})
3.本地存储
// Storage模块管理应用本地数据存储区,用于应用数据的保存和读取
plus.storage.setItem(key, value);
plus.storage.getItem(key);
4.扫一扫
mui.plusReady(function() {
var ws = plus.webview.currentWebview();
mui('#scan-title')[0].innerText = ws.title || '页面';
var barcode = plus.barcode.create('barcode', [plus.barcode.QR], {
// 1.扫码识别控件样式
top: '44px',
left: '0px',
frameColor: '#2E49C0',
scanbarColor: '#2E49C0'
});
plus.webview.currentWebview().append(barcode);
barcode.onmarked = function(type, result, file) {
// 3.调用第三方程序打开指定的URL
plus.runtime.openURL(result);
}
// 2.开始扫码识别
barcode.start({
conserve: true, // 默认false,扫码成功时是否将图片保存,如果true:通过onmarked回调函数的file参数返回保存文件的路径
filename: '_doc/scan'+ Date.now() + '.png', // 保存扫码成功时图片保存路径(doc文件夹下)
// vibrate: false, // 默认true,扫码成功时是否需要震动提醒
// sound: 'none' // 默认'default',提示音
});
})
5.摇一摇
mui.plusReady(function () {
// 1.监听设备加速度变化
watchAcceleration = plus.accelerometer.watchAcceleration(function(acc) {
const now = Date.now();
const threshold = 15; // 加速度变化阈值
if (!lastAcc) {
lastAcc = acc;
return;
}
// 计算加速度变化量(使用xAxis/yAxis/zAxis)
const delta =
Math.abs(acc.xAxis - lastAcc.xAxis) +
Math.abs(acc.yAxis - lastAcc.yAxis) +
Math.abs(acc.zAxis - lastAcc.zAxis);
lastAcc = acc;
// 2.检查阈值和防抖(判断触发摇一摇后的操作)
if (delta > threshold && now - lastShakeTime > 1000) {
// 3.摇一摇后的操作
handleShake();
lastShakeTime = now;
}
}, null, { frequency: 200 })
// 手动摇一摇
document.getElementById('btnShake').addEventListener('click', handleShake);
});
// 4.清理监听器
window.addEventListener('unload', () => {
if (watchAcceleration) plus.accelerometer.clearWatch(watchAcceleration);
});
6.拍照及相册选择
mui('#camera')[0].addEventListener('click', () => {
let cmr = plus.camera.getCamera();
cmr.captureImage(function(path) {
// 保存到相册
plus.gallery.save(path, function() {
console.log("保存图片到相册成功");
});
var imgs = document.createElement('img');
imgs.width = 100;
imgs.height = 100;
plus.storage.setItem("imgSrc", path)
// 生成 WebView 可识别的file://路径
const realPath = plus.io.convertLocalFileSystemURL(path);
imgs.src = realPath;
mui('#camera-img')[0].appendChild(imgs);
})
});
mui('#gallery')[0].addEventListener('click', () => {
plus.gallery.pick(
function(e) {
for (let i = 0; i < e.files.length; i++) {
var imgs = document.createElement('img');
imgs.width = 100;
imgs.height = 100;
imgs.src = e.files[i]
mui('#gallery-img')[0].appendChild(imgs);
}
},
function(e) {
console.log('取消选择图片');
}, {
multiple: true,
filter: 'image'
})
})
7.通讯录
mui.plusReady(function() {
let str = '';
// 1.获取通讯录对象
plus.contacts.getAddressBook('plus.contacts.ADDRESSBOOK_PHON', function(addressbook) {
// 2.通讯录中查找联系人
addressbook.find(null, function(data) {
for (let i = 0; i < data.length; i++) {
str +=
`<li class="mui-table-view-cell mui-media" data-phone="${data[i].phoneNumbers[0] ? data[i].phoneNumbers[0].value : ''}">
<a href="javascript:;">
<img class="mui-media-object mui-pull-left" src="${ data[i].photos[0] ? data[i].photos[0].value : './images/1.png' }">
<div class="mui-media-body">
${data[i].displayName}
<p class="mui-ellipsis">${data[i].phoneNumbers[0] ? data[i].phoneNumbers[0].value : ''}</p>
</div>
</a>
</li>`
}
// 3.页面渲染
mui('#list-ul')[0].innerHTML = str;
})
}, function(e) {
alert("Get address book failed: " + e.message);
})
// 4.点击事件
mui('ul').on('tap', 'li', function() {
var phone = this.getAttribute('data-phone');
window.location.href = 'tel:' + phone;
});
})
8.录音功能
mui.plusReady(function() {
let recorder = plus.audio.getRecorder();
function startAudio() {
recorder.record({
filename: "_doc/audio/" + Date.now() + ".wav"
}, function (recordFile) {
console.log("录音文件保存成功: " + recordFile);
}, function (error) {
console.log("录音失败: " + JSON.stringify(error));
recorder.stop();
recorder = null;
});
}
function endAudio() {
recorder.stop();
recorder = null;
console.log("录音已结束")
}
mui('#start-audio')[0].addEventListener('click', startAudio)
mui('#end-audio')[0].addEventListener('click', endAudio)
})