1. 程式人生 > >MUI框架-12-使用原生底部選項卡(凸出圖示案例)

MUI框架-12-使用原生底部選項卡(凸出圖示案例)

MUI框架-12-使用原生底部選項卡(凸出圖示案例)

今天,用 mui 做 app 時,遇到了可能各位都遇到過的頭疼問題:底部中間圖示凸起,如下圖:
在這裡插入圖片描述

最後有原始碼

【提示】:有人問我在 HBuilder 中看不到底部欄,請不要慌,程式碼沒有問題,在模擬器或者真機執行才會有,原生,原生。

1、mainifest.json程式碼修改如下,主要就是將官方 mui tab 底部凸起案例的字型圖示換成了圖片:

"launchwebview": {
	 "bottom": "0px",
	 "background": "#fff",
	 "subNViews": [
	 {
	 "id": "tabBar",
	 "styles": {
	 "bottom": "0px",
	 "left": "0",
	 "height": "50px",
	 "width": "100%",
	 "backgroundColor": "#fff"
	 },
	 "tags": [
	 {
	 "tag": "img",
	 "id": "homeIcon",
	 "src": "images/home_nor.png",
	 "position": {
	 "top": "4px",
	 "left": "10%",
	 "width": "25px",
	 "height": "40px"
	 }
	 },{
	 "tag": "img",
	 "id": "scheduleIcon",
	 "src": "images/schedule_nor.png",
	 "position": {
	 "top": "4px",
	 "left": "30%",
	 "width": "25px",
	 "height": "40px"
	 }
	 },{
	 "tag": "img",
	 "id": "goodsIcon",
	 "src": "images/goods_nor.png",
	 "position": {
	 "top": "4px",
	 "left": "65%",
	 "width": "25px",
	 "height": "40px"
	 }
	 },{
	 "tag": "img",
	 "id": "mineIcon",
	 "src": "images/mine_nor.png",
	 "position": {
	 "top": "4px",
	 "left": "85%",
	 "width": "25px",
	 "height": "40px"
	 }
	 }
	 ]
	 }
	 ]
	}

2、util.js程式碼修改如下(主要將字型顏色配置都換成了圖片,並且將subpages變成了物件陣列,增加了id和url欄位,這樣更加符合實際需求,新增了首頁,並且初始化顯示第一頁):

	var util = {
	 options: {
	 ACTIVE_SRC1: "images/home_click.png",
	 NORMAL_SRC1: "images/home_nor.png",
	 ACTIVE_SRC2: "images/schedule_click.png",
	 NORMAL_SRC2: "images/schedule_nor.png",
	 ACTIVE_SRC3: "images/goods_click.png",
	 NORMAL_SRC3: "images/goods_nor.png",
	 ACTIVE_SRC4: "images/mine_click.png",
	 NORMAL_SRC4: "images/mine_nor.png",
	 subpages: [{
	 url : 'pages/home.html',
	 id : 'home'
	 },{
	 url : 'pages/schedule.html',
	 id : 'schedule'
	 },{
	 url : 'pages/goods.html',
	 id : 'goods'
	 },{
	 url : 'pages/mine.html',
	 id : 'mine'
	 },]
	 },
	 /**
	  *  簡單封裝了繪製原生view控制元件的方法
	  *  繪製內容支援font(文字,字型圖示),圖片img , 矩形區域rect
	  */
	 drawNative: function(id, styles, tags) {
	 var view = new plus.nativeObj.View(id, styles, tags);
	 return view;
	 },
	 /**
	  * 初始化首個tab視窗 和 建立子webview視窗
	  */
	 initSubpage: function(aniShow) {
	 var subpage_style = {
	 top: 0,
	 bottom: 51
	 },
	 subpages = util.options.subpages,
	 self = plus.webview.currentWebview(),
	 temp = {};
	 //相容安卓上新增titleNView 和 設定沉浸式模式會遮蓋子webview內容
	 if(mui.os.android) {
	 if(plus.navigator.isImmersedStatusbar()) {
	 subpage_style.top += plus.navigator.getStatusbarHeight();
	 }
	 if(self.getTitleNView()) {
	 subpage_style.top += 40;
	 }
	 }
	 
	 // 初始化第一個tab項為首次顯示
	 temp[self.id] = "true";
	 mui.extend(aniShow, temp);
	 
	 // 初始化繪製首個tab按鈕
	 util.toggleNview(0);
	 
	 //預載入所有子頁面
	 for(var i = 0, len = subpages.length; i < len; i++) {
	 if(!plus.webview.getWebviewById(subpages[i].id)) {
	 var sub = plus.webview.create(subpages[i].url, subpages[i].id, subpage_style);
	 //初始化隱藏
	 sub.hide();
	 // append到當前父webview
	 self.append(sub);
	 }
	 }
	 
	 //初始化顯示第一個子頁面
	 plus.webview.show(plus.webview.getWebviewById(subpages[0].id));
	 
	 },
	 /**
	  * 點選切換tab視窗
	  */
	 changeSubpage: function(targetPage, activePage, aniShow) {
	 //若為iOS平臺或非首次顯示,則直接顯示
	 if(mui.os.ios || aniShow[targetPage]) {
	 plus.webview.show(targetPage);
	 } else {
	 //否則,使用fade-in動畫,且儲存變數
	 var temp = {};
	 temp[targetPage] = "true";
	 mui.extend(aniShow, temp);
	 plus.webview.show(targetPage, "fade-in", 300);
	 }
	 //隱藏當前 除了第一個父視窗
	 if(activePage !== plus.webview.getLaunchWebview()) {
	 plus.webview.hide(activePage);
	 }
	 },
	 /**
	  * 點選重繪底部tab (view控制元件)
	  */
	 toggleNview: function(currIndex) {
	 // 重繪當前tag 包括icon和text,所以執行兩個重繪操作
	 switch(currIndex){
	 case 0 :
	 util.updateSubNView(0, util.options.ACTIVE_SRC1);
	 util.updateSubNView(1, util.options.NORMAL_SRC2);
	 util.updateSubNView(2, util.options.NORMAL_SRC3);
	 util.updateSubNView(3, util.options.NORMAL_SRC4);
	 break;
	 case 1 :
	 util.updateSubNView(0, util.options.NORMAL_SRC1);
	 util.updateSubNView(1, util.options.ACTIVE_SRC2);
	 util.updateSubNView(2, util.options.NORMAL_SRC3);
	 util.updateSubNView(3, util.options.NORMAL_SRC4);
	 break;
	 case 2 :
	 util.updateSubNView(0, util.options.NORMAL_SRC1);
	 util.updateSubNView(1, util.options.NORMAL_SRC2);
	 util.updateSubNView(2, util.options.ACTIVE_SRC3);
	 util.updateSubNView(3, util.options.NORMAL_SRC4);
	 break;
	 case 3 :
	 util.updateSubNView(0, util.options.NORMAL_SRC1);
	 util.updateSubNView(1, util.options.NORMAL_SRC2);
	 util.updateSubNView(2, util.options.NORMAL_SRC3);
	 util.updateSubNView(3, util.options.ACTIVE_SRC4);
	 break;
	 }
	 },
	 /*
	  * 利用 plus.nativeObj.View 提供的 drawBitmap 方法更新 view 控制元件
	  */
	 updateSubNView: function(currIndex, src) {
	 var self = plus.webview.currentWebview(),
	 nviewEvent = plus.nativeObj.View.getViewById("tabBar"), // 獲取nview控制元件物件
	 nviewObj = self.getStyle().subNViews[0], // 獲取nview物件的屬性
	 currTag = nviewObj.tags[currIndex]; // 獲取當前需重繪的tag
	 nviewEvent.drawBitmap(src,'',currTag.position, currTag.id);
	 }
	};

3、index.html程式碼修改如下(主要將中間凸起的效果有原來的字型圖示改成了圖片):

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title>首頁</title>
		<script src="js/mui.min.js"></script>
		<link href="css/mui.min.css" rel="stylesheet" />
		<style>
			html,
			body {
				background-color: #efeff4;
			}
			
			.title {
				margin: 20px 15px 10px;
				color: #6d6d72;
				font-size: 15px;
				padding-bottom: 51px;
			}
		</style>
	</head>

	<body>
		<script src="js/util.js"></script>
		<script type="text/javascript">
			(function() {
				mui.init({
					swipeBack: true //啟用右滑關閉功能
				});
				mui.plusReady(function() {
					var self = plus.webview.currentWebview(),
						leftPos = Math.ceil((window.innerWidth - 60) / 2); // 設定凸起大圖示為水平居中
					/**
					 * drawNativeIcon 繪製凸起圓,
					 * 實現原理:
					 *   id為bg的tag 建立帶邊框的圓
					 *   id為bg2的tag 建立白色矩形遮住圓下半部分,只顯示凸起帶邊框部分
					 *   id為iconBg的紅色背景圖
					 *   id為icon的字型圖示
					 *   注意建立先後順序,建立越晚的層級越高
					 */
					var drawNativeIcon = util.drawNative('icon', {
						bottom: '5px',
						left: leftPos + 'px',
						width: '60px',
						height: '60px'
					}, [{
						tag: 'rect',
						id: 'bg',
						position: {
							top: '1px',
							left: '0px',
							width: '100%',
							height: '100%'
						},
						rectStyles: {
							color: '#fff',
							radius: '50%',
							borderColor: '#ccc',
							borderWidth: '1px'
						}
					}, {
						tag: 'rect',
						id: 'bg2',
						position: {
							bottom: '-0.5px',
							left: '0px',
							width: '100%',
							height: '45px'
						},
						rectStyles: {
							color: '#fff'
						}
					}, {
						tag: 'rect',
						id: 'iconBg',
						position: {
							top: '5px',
							left: '5px',
							width: '50px',
							height: '50px'
						},
						rectStyles: {
							color: '#0ab88e',
							radius: '50%'
						}
					}, {
						tag: 'img',
						id: 'icon',
						position: {
							top: '15px',
							left: '15px',
							width: '30px',
							height: '30px'
						},
						src: 'images/icon_scan.png'
					}]);
					// 將繪製的凸起 append 到父webview中
					self.append(drawNativeIcon);

					//凸起圓的點選事件
					var active_color = '#fff';
					drawNativeIcon.addEventListener('click', function(e) {
						mui.openWindow({
							id: 'scan',
							url: 'pages/scan.html'
						})
					});
					// 中間凸起圖示繪製及監聽點選 完畢

					// 建立子webview視窗 並初始化
					var aniShow = {};
					util.initSubpage(aniShow);

					//初始化相關引數
					var nview = plus.nativeObj.View.getViewById('tabBar'),
						activePage = plus.webview.currentWebview(),
						targetPage,
						subpages = util.options.subpages,
						pageW = window.innerWidth,
						currIndex = 0;

					/**
					 * 根據判斷view控制元件點選位置判斷切換的tab
					 */
					nview.addEventListener('click', function(e) {
						var clientX = e.clientX;
						if(clientX >= 0 && clientX <= parseInt(pageW * 0.25)) {
							currIndex = 0;
						} else if(clientX > parseInt(pageW * 0.25) && clientX <= parseInt(pageW * 0.45)) {
							currIndex = 1;
						} else if(clientX > parseInt(pageW * 0.45) && clientX <= parseInt(pageW * 0.8)) {
							currIndex = 2;
						} else {
							currIndex = 3;
						}
						// 匹配對應tab視窗
						if(plus.webview.getWebviewById(subpages[currIndex].id) == plus.webview.currentWebview()) {
							return;
						} else {
							targetPage = plus.webview.getWebviewById(subpages[currIndex].id);
						}

						//底部選項卡切換
						util.toggleNview(currIndex);
						// 子頁面切換
						util.changeSubpage(targetPage, activePage, aniShow);
						//更新當前活躍的頁面
						activePage = targetPage;

					});
				});
			})();
		</script>
	</body>

</html>

原始碼下載地址:

更多文章: