MUI框架-12-使用原生底部选项卡(凸出图标案例)

水深无声 2022-04-18 01:44 690阅读 0赞

MUI框架-12-使用原生底部选项卡(凸出图标案例)

今天,用 mui 做 app 时,遇到了可能各位都遇到过的头疼问题:底部中间图标凸起,如下图:
在这里插入图片描述

最后有源代码

【提示】:有人问我在 HBuilder 中看不到底部栏,请不要慌,代码没有问题,在模拟器或者真机运行才会有,原生,原生。

1、mainifest.json代码修改如下,主要就是将官方 mui tab 底部凸起案例的字体图标换成了图片:

  1. "launchwebview": {
  2. "bottom": "0px",
  3. "background": "#fff",
  4. "subNViews": [
  5. {
  6. "id": "tabBar",
  7. "styles": {
  8. "bottom": "0px",
  9. "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字段,这样更加符合实际需求,新增了首页,并且初始化显示第一页):

  1. var util = {
  2. options: {
  3. ACTIVE_SRC1: "images/home_click.png",
  4. NORMAL_SRC1: "images/home_nor.png",
  5. ACTIVE_SRC2: "images/schedule_click.png",
  6. NORMAL_SRC2: "images/schedule_nor.png",
  7. ACTIVE_SRC3: "images/goods_click.png",
  8. NORMAL_SRC3: "images/goods_nor.png",
  9. ACTIVE_SRC4: "images/mine_click.png",
  10. NORMAL_SRC4: "images/mine_nor.png",
  11. subpages: [{
  12. url : 'pages/home.html',
  13. id : 'home'
  14. },{
  15. url : 'pages/schedule.html',
  16. id : 'schedule'
  17. },{
  18. url : 'pages/goods.html',
  19. id : 'goods'
  20. },{
  21. url : 'pages/mine.html',
  22. id : 'mine'
  23. },]
  24. },
  25. /**
  26. * 简单封装了绘制原生view控件的方法
  27. * 绘制内容支持font(文本,字体图标),图片img , 矩形区域rect
  28. */
  29. drawNative: function(id, styles, tags) {
  30. var view = new plus.nativeObj.View(id, styles, tags);
  31. return view;
  32. },
  33. /**
  34. * 初始化首个tab窗口 和 创建子webview窗口
  35. */
  36. initSubpage: function(aniShow) {
  37. var subpage_style = {
  38. top: 0,
  39. bottom: 51
  40. },
  41. subpages = util.options.subpages,
  42. self = plus.webview.currentWebview(),
  43. temp = {};
  44. //兼容安卓上添加titleNView 和 设置沉浸式模式会遮盖子webview内容
  45. if(mui.os.android) {
  46. if(plus.navigator.isImmersedStatusbar()) {
  47. subpage_style.top += plus.navigator.getStatusbarHeight();
  48. }
  49. if(self.getTitleNView()) {
  50. subpage_style.top += 40;
  51. }
  52. }
  53. // 初始化第一个tab项为首次显示
  54. temp[self.id] = "true";
  55. mui.extend(aniShow, temp);
  56. // 初始化绘制首个tab按钮
  57. util.toggleNview(0);
  58. //预加载所有子页面
  59. for(var i = 0, len = subpages.length; i < len; i++) {
  60. if(!plus.webview.getWebviewById(subpages[i].id)) {
  61. var sub = plus.webview.create(subpages[i].url, subpages[i].id, subpage_style);
  62. //初始化隐藏
  63. sub.hide();
  64. // append到当前父webview
  65. self.append(sub);
  66. }
  67. }
  68. //初始化显示第一个子页面
  69. plus.webview.show(plus.webview.getWebviewById(subpages[0].id));
  70. },
  71. /**
  72. * 点击切换tab窗口
  73. */
  74. changeSubpage: function(targetPage, activePage, aniShow) {
  75. //若为iOS平台或非首次显示,则直接显示
  76. if(mui.os.ios || aniShow[targetPage]) {
  77. plus.webview.show(targetPage);
  78. } else {
  79. //否则,使用fade-in动画,且保存变量
  80. var temp = {};
  81. temp[targetPage] = "true";
  82. mui.extend(aniShow, temp);
  83. plus.webview.show(targetPage, "fade-in", 300);
  84. }
  85. //隐藏当前 除了第一个父窗口
  86. if(activePage !== plus.webview.getLaunchWebview()) {
  87. plus.webview.hide(activePage);
  88. }
  89. },
  90. /**
  91. * 点击重绘底部tab (view控件)
  92. */
  93. toggleNview: function(currIndex) {
  94. // 重绘当前tag 包括icon和text,所以执行两个重绘操作
  95. switch(currIndex){
  96. case 0 :
  97. util.updateSubNView(0, util.options.ACTIVE_SRC1);
  98. util.updateSubNView(1, util.options.NORMAL_SRC2);
  99. util.updateSubNView(2, util.options.NORMAL_SRC3);
  100. util.updateSubNView(3, util.options.NORMAL_SRC4);
  101. break;
  102. case 1 :
  103. util.updateSubNView(0, util.options.NORMAL_SRC1);
  104. util.updateSubNView(1, util.options.ACTIVE_SRC2);
  105. util.updateSubNView(2, util.options.NORMAL_SRC3);
  106. util.updateSubNView(3, util.options.NORMAL_SRC4);
  107. break;
  108. case 2 :
  109. util.updateSubNView(0, util.options.NORMAL_SRC1);
  110. util.updateSubNView(1, util.options.NORMAL_SRC2);
  111. util.updateSubNView(2, util.options.ACTIVE_SRC3);
  112. util.updateSubNView(3, util.options.NORMAL_SRC4);
  113. break;
  114. case 3 :
  115. util.updateSubNView(0, util.options.NORMAL_SRC1);
  116. util.updateSubNView(1, util.options.NORMAL_SRC2);
  117. util.updateSubNView(2, util.options.NORMAL_SRC3);
  118. util.updateSubNView(3, util.options.ACTIVE_SRC4);
  119. break;
  120. }
  121. },
  122. /*
  123. * 利用 plus.nativeObj.View 提供的 drawBitmap 方法更新 view 控件
  124. */
  125. updateSubNView: function(currIndex, src) {
  126. var self = plus.webview.currentWebview(),
  127. nviewEvent = plus.nativeObj.View.getViewById("tabBar"), // 获取nview控件对象
  128. nviewObj = self.getStyle().subNViews[0], // 获取nview对象的属性
  129. currTag = nviewObj.tags[currIndex]; // 获取当前需重绘的tag
  130. nviewEvent.drawBitmap(src,'',currTag.position, currTag.id);
  131. }
  132. };

3、index.html代码修改如下(主要将中间凸起的效果有原来的字体图标改成了图片):

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
  6. <title>首页</title>
  7. <script src="js/mui.min.js"></script>
  8. <link href="css/mui.min.css" rel="stylesheet" />
  9. <style>
  10. html,
  11. body {
  12. background-color: #efeff4;
  13. }
  14. .title {
  15. margin: 20px 15px 10px;
  16. color: #6d6d72;
  17. font-size: 15px;
  18. padding-bottom: 51px;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <script src="js/util.js"></script>
  24. <script type="text/javascript">
  25. (function() {
  26. mui.init({
  27. swipeBack: true //启用右滑关闭功能
  28. });
  29. mui.plusReady(function() {
  30. var self = plus.webview.currentWebview(),
  31. leftPos = Math.ceil((window.innerWidth - 60) / 2); // 设置凸起大图标为水平居中
  32. /**
  33. * drawNativeIcon 绘制凸起圆,
  34. * 实现原理:
  35. * id为bg的tag 创建带边框的圆
  36. * id为bg2的tag 创建白色矩形遮住圆下半部分,只显示凸起带边框部分
  37. * id为iconBg的红色背景图
  38. * id为icon的字体图标
  39. * 注意创建先后顺序,创建越晚的层级越高
  40. */
  41. var drawNativeIcon = util.drawNative('icon', {
  42. bottom: '5px',
  43. left: leftPos + 'px',
  44. width: '60px',
  45. height: '60px'
  46. }, [{
  47. tag: 'rect',
  48. id: 'bg',
  49. position: {
  50. top: '1px',
  51. left: '0px',
  52. width: '100%',
  53. height: '100%'
  54. },
  55. rectStyles: {
  56. color: '#fff',
  57. radius: '50%',
  58. borderColor: '#ccc',
  59. borderWidth: '1px'
  60. }
  61. }, {
  62. tag: 'rect',
  63. id: 'bg2',
  64. position: {
  65. bottom: '-0.5px',
  66. left: '0px',
  67. width: '100%',
  68. height: '45px'
  69. },
  70. rectStyles: {
  71. color: '#fff'
  72. }
  73. }, {
  74. tag: 'rect',
  75. id: 'iconBg',
  76. position: {
  77. top: '5px',
  78. left: '5px',
  79. width: '50px',
  80. height: '50px'
  81. },
  82. rectStyles: {
  83. color: '#0ab88e',
  84. radius: '50%'
  85. }
  86. }, {
  87. tag: 'img',
  88. id: 'icon',
  89. position: {
  90. top: '15px',
  91. left: '15px',
  92. width: '30px',
  93. height: '30px'
  94. },
  95. src: 'images/icon_scan.png'
  96. }]);
  97. // 将绘制的凸起 append 到父webview中
  98. self.append(drawNativeIcon);
  99. //凸起圆的点击事件
  100. var active_color = '#fff';
  101. drawNativeIcon.addEventListener('click', function(e) {
  102. mui.openWindow({
  103. id: 'scan',
  104. url: 'pages/scan.html'
  105. })
  106. });
  107. // 中间凸起图标绘制及监听点击 完毕
  108. // 创建子webview窗口 并初始化
  109. var aniShow = {};
  110. util.initSubpage(aniShow);
  111. //初始化相关参数
  112. var nview = plus.nativeObj.View.getViewById('tabBar'),
  113. activePage = plus.webview.currentWebview(),
  114. targetPage,
  115. subpages = util.options.subpages,
  116. pageW = window.innerWidth,
  117. currIndex = 0;
  118. /**
  119. * 根据判断view控件点击位置判断切换的tab
  120. */
  121. nview.addEventListener('click', function(e) {
  122. var clientX = e.clientX;
  123. if(clientX >= 0 && clientX <= parseInt(pageW * 0.25)) {
  124. currIndex = 0;
  125. } else if(clientX > parseInt(pageW * 0.25) && clientX <= parseInt(pageW * 0.45)) {
  126. currIndex = 1;
  127. } else if(clientX > parseInt(pageW * 0.45) && clientX <= parseInt(pageW * 0.8)) {
  128. currIndex = 2;
  129. } else {
  130. currIndex = 3;
  131. }
  132. // 匹配对应tab窗口
  133. if(plus.webview.getWebviewById(subpages[currIndex].id) == plus.webview.currentWebview()) {
  134. return;
  135. } else {
  136. targetPage = plus.webview.getWebviewById(subpages[currIndex].id);
  137. }
  138. //底部选项卡切换
  139. util.toggleNview(currIndex);
  140. // 子页面切换
  141. util.changeSubpage(targetPage, activePage, aniShow);
  142. //更新当前活跃的页面
  143. activePage = targetPage;
  144. });
  145. });
  146. })();
  147. </script>
  148. </body>
  149. </html>

源码下载地址:

  • 地址:https://download.csdn.net/download/qq_40147863/10768519

更多文章:

  • 博客园:MUI 框架
  • CSDN:MUI 框架

发表评论

表情:
评论列表 (有 0 条评论,690人围观)

还没有评论,来说两句吧...

相关阅读

    相关 MUI实现侧方选项功能

    引言 对于线上行业而言,分类栏目可以帮助我们快速找到所需要的商品或文章等。而现在实现这种分类效果的大多数以侧方选项卡的形式来实现,所以掌握该技能可以大大的提高平时的开...

    相关 MUI底部二级菜单

    引言 底部二级菜单,笔者在原生的APP很少看到该功能,而在微信公众号倒是挺常见的,不过既然在MUI中看到此技巧,那笔者就在此记录一下方便自己日后查阅,同时也希望可以帮...

    相关 mui底部导航

    在网上找了一个mui的底部导航,用起来还不错,但是已经找不到出处了。 修改了一下之后,原谅我厚脸皮的发个原创了。 用的是自定义的图标,如果不会,可以在我的博客里面找找 !