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

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

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

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

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

1、mainifest.json代码修改如下,主要就是将官方mui tab底部凸起案例的字体图标换成了图片:
01 "launchwebview": {
02  "bottom""0px",
03  "background""#fff",
04  "subNViews": [
05  {
06  "id""tabBar",
07  "styles": {
08  "bottom""0px",
09  "left""0",
10  "height""50px",
11  "width""100%",
12  "backgroundColor""#fff"
13  },
14  "tags": [
15  {
16  "tag""img",
17  "id""homeIcon",
18  "src""images/home_nor.png",
19  "position": {
20  "top""4px",
21  "left""10%",
22  "width""25px",
23  "height""40px"
24  }
25  },{
26  "tag""img",
27  "id""scheduleIcon",
28  "src""images/schedule_nor.png",
29  "position": {
30  "top""4px",
31  "left""30%",
32  "width""25px",
33  "height""40px"
34  }
35  },{
36  "tag""img",
37  "id""goodsIcon",
38  "src""images/goods_nor.png",
39  "position": {
40  "top""4px",
41  "left""65%",
42  "width""25px",
43  "height""40px"
44  }
45  },{
46  "tag""img",
47  "id""mineIcon",
48  "src""images/mine_nor.png",
49  "position": {
50  "top""4px",
51  "left""85%",
52  "width""25px",
53  "height""40px"
54  }
55  }
56  ]
57  }
58  ]
59 }
2、util.js代码修改如下(主要将字体颜色配置都换成了图片,并且将subpages变成了对象数组,增加了id和url字段,这样更加符合实际需求,新增了首页,并且初始化显示第一页):
001 var util = {
002  options: {
003  ACTIVE_SRC1: "images/home_click.png",
004  NORMAL_SRC1: "images/home_nor.png",
005  ACTIVE_SRC2: "images/schedule_click.png",
006  NORMAL_SRC2: "images/schedule_nor.png",
007  ACTIVE_SRC3: "images/goods_click.png",
008  NORMAL_SRC3: "images/goods_nor.png",
009  ACTIVE_SRC4: "images/mine_click.png",
010  NORMAL_SRC4: "images/mine_nor.png",
011  subpages: [{
012  url : 'pages/home.html',
013  id : 'home'
014  },{
015  url : 'pages/schedule.html',
016  id : 'schedule'
017  },{
018  url : 'pages/goods.html',
019  id : 'goods'
020  },{
021  url : 'pages/mine.html',
022  id : 'mine'
023  },]
024  },
025  /**
026   *  简单封装了绘制原生view控件的方法
027   *  绘制内容支持font(文本,字体图标),图片img , 矩形区域rect
028   */
029  drawNative: function(id, styles, tags) {
030  var view = new plus.nativeObj.View(id, styles, tags);
031  return view;
032  },
033  /**
034   * 初始化首个tab窗口 和 创建子webview窗口
035   */
036  initSubpage: function(aniShow) {
037  var subpage_style = {
038  top: 0,
039  bottom: 51
040  },
041  subpages = util.options.subpages,
042  self = plus.webview.currentWebview(),
043  temp = {};
044  //兼容安卓上添加titleNView 和 设置沉浸式模式会遮盖子webview内容
045  if(mui.os.android) {
046  if(plus.navigator.isImmersedStatusbar()) {
047  subpage_style.top += plus.navigator.getStatusbarHeight();
048  }
049  if(self.getTitleNView()) {
050  subpage_style.top += 40;
051  }
052  }
053  
054  // 初始化第一个tab项为首次显示
055  temp[self.id] = "true";
056  mui.extend(aniShow, temp);
057  
058  // 初始化绘制首个tab按钮
059  util.toggleNview(0);
060  
061  //预加载所有子页面
062  for(var i = 0, len = subpages.length; i < len; i++) {
063  if(!plus.webview.getWebviewById(subpages[i].id)) {
064  var sub = plus.webview.create(subpages[i].url, subpages[i].id, subpage_style);
065  //初始化隐藏
066  sub.hide();
067  // append到当前父webview
068  self.append(sub);
069  }
070  }
071  
072  //初始化显示第一个子页面
073  plus.webview.show(plus.webview.getWebviewById(subpages[0].id));
074  
075  },
076  /**
077   * 点击切换tab窗口
078   */
079  changeSubpage: function(targetPage, activePage, aniShow) {
080  //若为iOS平台或非首次显示,则直接显示
081  if(mui.os.ios || aniShow[targetPage]) {
082  plus.webview.show(targetPage);
083  else {
084  //否则,使用fade-in动画,且保存变量
085  var temp = {};
086  temp[targetPage] = "true";
087  mui.extend(aniShow, temp);
088  plus.webview.show(targetPage, "fade-in", 300);
089  }
090  //隐藏当前 除了第一个父窗口
091  if(activePage !== plus.webview.getLaunchWebview()) {
092  plus.webview.hide(activePage);
093  }
094  },
095  /**
096   * 点击重绘底部tab (view控件)
097   */
098  toggleNview: function(currIndex) {
099  // 重绘当前tag 包括icon和text,所以执行两个重绘操作
100  switch(currIndex){
101  case 0 :
102  util.updateSubNView(0, util.options.ACTIVE_SRC1);
103  util.updateSubNView(1, util.options.NORMAL_SRC2);
104  util.updateSubNView(2, util.options.NORMAL_SRC3);
105  util.updateSubNView(3, util.options.NORMAL_SRC4);
106  break;
107  case 1 :
108  util.updateSubNView(0, util.options.NORMAL_SRC1);
109  util.updateSubNView(1, util.options.ACTIVE_SRC2);
110  util.updateSubNView(2, util.options.NORMAL_SRC3);
111  util.updateSubNView(3, util.options.NORMAL_SRC4);
112  break;
113  case 2 :
114  util.updateSubNView(0, util.options.NORMAL_SRC1);
115  util.updateSubNView(1, util.options.NORMAL_SRC2);
116  util.updateSubNView(2, util.options.ACTIVE_SRC3);
117  util.updateSubNView(3, util.options.NORMAL_SRC4);
118  break;
119  case 3 :
120  util.updateSubNView(0, util.options.NORMAL_SRC1);
121  util.updateSubNView(1, util.options.NORMAL_SRC2);
122  util.updateSubNView(2, util.options.NORMAL_SRC3);
123  util.updateSubNView(3, util.options.ACTIVE_SRC4);
124  break;
125  }
126  },
127  /*
128   * 利用 plus.nativeObj.View 提供的 drawBitmap 方法更新 view 控件
129   */
130  updateSubNView: function(currIndex, src) {
131  var self = plus.webview.currentWebview(),
132  nviewEvent = plus.nativeObj.View.getViewById("tabBar"), // 获取nview控件对象
133  nviewObj = self.getStyle().subNViews[0], // 获取nview对象的属性
134  currTag = nviewObj.tags[currIndex]; // 获取当前需重绘的tag
135  nviewEvent.drawBitmap(src,'',currTag.position, currTag.id);
136  }
137 };
3、index.html代码修改如下(主要将中间凸起的效果有原来的字体图标改成了图片):
001 <!DOCTYPE html>
002 <html>
003 <head>
004 <meta charset="UTF-8">
005 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
006 <title>首页</title>
007 <script src="js/mui.min.js"></script>
008 <link href="css/mui.min.css" rel="stylesheet" />
009 <style>
010 html,
011 body {
012  background-color: #efeff4;
013 }
014  
015 .title {
016  margin: 20px 15px 10px;
017  color: #6d6d72;
018  font-size: 15px;
019  padding-bottom: 51px;
020 }
021 </style>
022 </head>
023  
024 <body>
025  <script src="js/util.js"></script>
026  <script type="text/javascript">
027  (function() {
028  mui.init({
029  swipeBack: true //启用右滑关闭功能
030  });
031  mui.plusReady(function() {
032  var self = plus.webview.currentWebview(),
033  leftPos = Math.ceil((window.innerWidth - 60) / 2); // 设置凸起大图标为水平居中
034  /**
035   * drawNativeIcon 绘制凸起圆,
036   * 实现原理:
037   *   id为bg的tag 创建带边框的圆
038   *   id为bg2的tag 创建白色矩形遮住圆下半部分,只显示凸起带边框部分
039   *   id为iconBg的红色背景图
040   *   id为icon的字体图标
041   *   注意创建先后顺序,创建越晚的层级越高
042   */
043  var drawNativeIcon = util.drawNative('icon', {
044  bottom: '5px',
045  left: leftPos + 'px',
046  width: '60px',
047  height: '60px'
048  }, [{
049  tag: 'rect',
050  id: 'bg',
051  position: {
052  top: '1px',
053  left: '0px',
054  width: '100%',
055  height: '100%'
056  },
057  rectStyles: {
058  color: '#fff',
059  radius: '50%',
060  borderColor: '#ccc',
061  borderWidth: '1px'
062  }
063  }, {
064  tag: 'rect',
065  id: 'bg2',
066  position: {
067  bottom: '-0.5px',
068  left: '0px',
069  width: '100%',
070  height: '45px'
071  },
072  rectStyles: {
073  color: '#fff'
074  }
075  }, {
076  tag: 'rect',
077  id: 'iconBg',
078  position: {
079  top: '5px',
080  left: '5px',
081  width: '50px',
082  height: '50px'
083  },
084  rectStyles: {
085  color: '#0ab88e',
086  radius: '50%'
087  }
088  },{
089  tag: 'img',
090  id: 'icon',
091  position: {
092  top: '15px',
093  left: '15px',
094  width: '30px',
095  height: '30px'
096  },
097  src: 'images/icon_scan.png'
098  }]);
099  // 将绘制的凸起 append 到父webview中
100  self.append(drawNativeIcon);
101  
102  
103  //凸起圆的点击事件
104  var active_color = '#fff';
105  drawNativeIcon.addEventListener('click', function(e) {
106  mui.openWindow({
107  id : 'scan',
108  url : 'pages/scan.html'
109  })
110  });
111  // 中间凸起图标绘制及监听点击 完毕
112  
113  // 创建子webview窗口 并初始化
114  var aniShow = {};
115  util.initSubpage(aniShow);
116   
117  //初始化相关参数
118  var nview = plus.nativeObj.View.getViewById('tabBar'),
119  activePage = plus.webview.currentWebview(),
120  targetPage,
121  subpages = util.options.subpages,
122  pageW = window.innerWidth,
123  currIndex = 0;
124   
125  /**
126   * 根据判断view控件点击位置判断切换的tab
127   */
128  nview.addEventListener('click', function(e) {
129  var clientX = e.clientX;
130  if(clientX >= 0 && clientX <= parseInt(pageW * 0.25)) {
131  currIndex = 0;
132  } else if(clientX > parseInt(pageW * 0.25) && clientX <= parseInt(pageW * 0.45)) {
133  currIndex = 1;
134  } else if(clientX > parseInt(pageW * 0.45) && clientX <= parseInt(pageW * 0.8)) {
135  currIndex = 2;
136  } else {
137  currIndex = 3;
138  }
139  // 匹配对应tab窗口
140  if(plus.webview.getWebviewById(subpages[currIndex].id) ==  plus.webview.currentWebview()){
141  return;
142  }else{
143  targetPage = plus.webview.getWebviewById(subpages[currIndex].id);
144  }
145  
146  //底部选项卡切换
147  util.toggleNview(currIndex);
148  // 子页面切换
149  util.changeSubpage(targetPage, activePage, aniShow);
150  //更新当前活跃的页面
151  activePage = targetPage;
152  
153  });
154  });
155  })();
156  </script>
157 </body>
158 </html>
下面是源码下载:

nativeTab_5imoban

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