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

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

mui 底部凸起

    其实官方已经给出详细解决方案: 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字段,这样更加符合实际需求,新增了首页,并且初始化显示第一页):
001var 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>
010html,
011body {
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,将图片替换即可。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
在实现 MUI 底部选项卡的跳转功能时,可以使用 `<BottomNavigation>` 和 `<BottomNavigationAction>` 组件来创建底部导航栏和选项卡。 首先,你需要导入相关的组件: ```jsx import React, { useState } from 'react'; import { BottomNavigation, BottomNavigationAction } from '@mui/material'; import { Home, Explore, Favorite } from '@mui/icons-material'; ``` 然后,你可以创建一个函数组件,并在组件中添加底部导航栏和选项卡的代码: ```jsx function BottomTabs() { const [value, setValue] = useState(0); // 用于保存当前选中的选项卡索引 const handleTabChange = (event, newValue) => { setValue(newValue); // 更新选中的选项卡索引 }; return ( <BottomNavigation value={value} onChange={handleTabChange}> <BottomNavigationAction label="Home" icon={<Home />} /> <BottomNavigationAction label="Explore" icon={<Explore />} /> <BottomNavigationAction label="Favorite" icon={<Favorite />} /> </BottomNavigation> ); } ``` 在上面的代码中,我们使用 `useState` 钩子来创建一个名为 `value` 的状态变量,用于保存当前选中的选项卡索引。`handleTabChange` 函数用于处理选项卡变动事件,并更新 `value` 的值。 最后,将 `BottomTabs` 组件添加到你的页面中即可: ```jsx function App() { return ( <div> {/* 其他内容 */} <BottomTabs /> </div> ); } ``` 这样,你就实现了 MUI 底部选项卡的跳转功能。当用户点击不同的选项卡时,会触发 `handleTabChange` 函数,并更新 `value` 的值,从而实现页面的跳转效果。你可以根据自己的需求,在每个选项卡的 `onClick` 事件中添加相应的跳转逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值