首页 > 建站教程 > APP开发,混合APP >  mui APP tab选项卡底部凸出图标解决实例正文

mui APP tab选项卡底部凸出图标解决实例

今天,我爱模板网用mui做app时,遇到了可能各位都遇到过的头疼问题:底部中间图标凸起,如下图:

mui 底部凸起

    其实官方已经给出详细解决方案:tab选项卡示例教程-基于subnview模式的原生tab(含底部凸起大图标)

    但是官方的案例首页是写死的,并且图标是字体图标,不是图片,还有其他一些效果都和我们平时的需求不同,所以,我爱模板网对其进行了改良,下面是相关代码,具体就不解释了:

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>
下面是源码下载:

nativeTab_5imoban

注:代码注释非常详细,可以对比着官方demo进行修改,也可以直接使用我爱模板网修改的demo,将图片替换即可。