(一)vue
首先看效果tab实现
<template>
<div class="page-tabbar">
<div class="page-wrap">
<!-- 自定义头组件 -->
<titlebar
leftTitle="微信(11)"
:search="mysearch"
:add="myadd"
:rightFirstImg="require('../assets/ic_search.png')"
:rightSecondImg="require('../assets/ic_add.png')"
/>
<div style="margin-top:48px;">
<!-- <mt-cell class="page-part" title="当前选中" :value="selected" /> -->
</div>
<mt-tab-container class="page-tabbar-container" v-model="selected">
<mt-tab-container-item id="message">
<messagelist></messagelist>
</mt-tab-container-item>
<mt-tab-container-item id="contact">
<contact></contact>
</mt-tab-container-item>
<mt-tab-container-item id="find">
<find></find>
</mt-tab-container-item>
<mt-tab-container-item id="me">
<me></me>
</mt-tab-container-item>
</mt-tab-container>
</div>
<!-- 这里为了方便直接写死四个,最好是定义一个 json 循环遍历出来,这样
可以动态匹配,tab 图片和内容从服务器拿都没有问题,mt-tab-container-item 同理-->
<mt-tabbar v-model="selected" fixed>
<mt-tab-item id="message" @click.native="changeState(0)">
<tabbaricon
:normalImage="require('../assets/ic_weixin_normal.png')"
:selectedImage="require('../assets/ic_weixin_selected.png')"
:focused="currentIndex[0].isSelect"
/>
微信
</mt-tab-item>
<mt-tab-item id="contact" @click.native="changeState(1)">
<tabbaricon
:normalImage="require('../assets/ic_contacts_normal.png')"
:selectedImage="require('../assets/ic_contacts_selected.png')"
:focused="currentIndex[1].isSelect"
/>
通讯录
</mt-tab-item>
<mt-tab-item id="find" @click.native="changeState(2)">
<tabbaricon
:normalImage="require('../assets/ic_find_normal.png')"
:selectedImage="require('../assets/ic_find_selected.png')"
:focused="currentIndex[2].isSelect"
/>
发现
</mt-tab-item>
<mt-tab-item id="me" @click.native="changeState(3)">
<tabbaricon
:normalImage="require('../assets/ic_me_normal.png')"
:selectedImage="require('../assets/ic_me_selected.png')"
:focused="currentIndex[3].isSelect"
/>
我
</mt-tab-item>
</mt-tabbar>
</div>
</template>
<script>
import TitleBar from './common/TitleBar'
import TabBarIcon from './common/TabBarIcon'
import MessageList from './message/MessageList'
import Contact from './contact/Contact'
import Find from './find/Find'
import Me from './me/Me'
export default {
name: 'Home',
data() {
return {
selected: 'message',
// 默认 tab 的选中情况
currentIndex:[
{isSelect:true},
{isSelect:false},
{isSelect:false},
{isSelect:false},
]
};
},
methods:{
mysearch() {
console.log('搜索')
},
myadd() {
console.log('+')
},
// 改变选中 tab 的状态,根据状态来改变要显示选中与否的图片
changeState(n){
for(var i=0;i<this.currentIndex.length;i++){
if(i==n){ // 当前选中的为 true
this.currentIndex[i].isSelect = true
}else { // 其它的为 false
this.currentIndex[i].isSelect = false
}
}
}
},
components:{
'titlebar':TitleBar,
'tabbaricon':TabBarIcon,
'messagelist':MessageList,
'contact':Contact,
'find':Find,
'me':Me
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.page-tabbar {
overflow: hidden;
/* height: 100vh; */
}
/*修改tab 默认文字的颜色*/
.mint-tabbar > .mint-tab-item{
color:#999999;
}
/* 修改默认 tab 选中文字的样式 */
.mint-tabbar > .mint-tab-item.is-selected {
background-color: transparent;
color:#45C018;
}
.page-wrap {
overflow: auto;
/* height: 92%; */
padding-bottom: 60px;
}
</style>
(二)微信小程序
默认支持,无需引入组件
app.json
"tabBar": {
// 背景色
"backgroundColor": "#bc162c",
// 背景文字
"color": "#8a8a8a",
// 高亮背景文字
"selectedColor":"#fff",
"list": [
{
"pagePath": "pages/index/index", // 路由页面
"text": "首页", // 路由文字
"iconPath":"images/home1.png", // 默认显示图标必须是图片81*81
"selectedIconPath":"images/home.png" // 高亮显示图标
},
{
"pagePath": "pages/logs/logs",
"text": "日志",
"iconPath":"images/log1.png",
"selectedIconPath":"images/log.png"
}
]
}
(三)安卓
窗口布局
外层采用RelativeLayout布局,内层放入一个FrameLayout与一个LinearLayout布局,LinearLayout放置在窗口底部,在其内部放入radiogroup及radiobutton
<FrameLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_above="@+id/linearLayout"
android:id="@+id/main_fragment">
</FrameLayout>
LinearLayout布局代码
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:id="@+id/linearLayout">
radiogroup及radiobutton部分代码
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton//该配置来源于网上,直接使用即可
android:id="@+id/bt_bottom_near"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_weight="1"
android:background="@android:color/transparent"
android:button="@null"
android:checked="true"
android:drawableTop="@drawable/near_bt_selector"//设置背景图片变换效果
android:gravity="center_horizontal|bottom"
android:paddingTop="2dp"
android:text="@string/bt_bottom_near"
android:textColor="@drawable/bottom_bt_text_color" />//设置字体变换效果
......
near_bt_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="@drawable/near_active">//选中状态显示效果
</item>
<item android:state_checked="false"
android:drawable="@drawable/near_black"></item>//未被选中样式效果
</selector>
bottom_bt_text_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="@android:color/holo_orange_dark"/>//选中颜色
<item android:state_checked="false" android:color="@android:color/black"/>//未被选中颜色
<item android:color="@android:color/black"/>//初始颜色
</selector>
实现打开fragment,fragment之间切换,定义按钮的click事件
@Override
public void onClick(View v) {
MsgFragment msgFragment = new MsgFragment();//新建fragment实例
Bundle args = new Bundle();//绑定参数
args.putString("args", getResources().getString(R.string.bt_bottom_msg));
msgFragment.setArguments(args);
fragmentManager.beginTransaction().replace(R.id.main_fragment, msgFragment).commit();//记得提交
}
fragment类的实现,需要继承Fragment基类
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_msg, container, false);//获得视图
tvMsgShow = (TextView) view.findViewById(R.id.msgShow);
tvMsgShow.setText(getArguments().getString("args"));//显示参数值
return view;
}
(四)IOS
采用了UITabBarController+UINavigationController的设计方式
AppDelegate.m
TabBarController *tabVC = [[TabBarController alloc]init];
self.window.rootViewController = tabVC;
TabBarController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self addChildVc:[[ChatViewController alloc] init] title:@"Chat" image:@"tabbar_home" selectedImage:@"tabbar_home_selected"];
[self addChildVc:[[ContactsListViewController alloc] init] title:@"Contact" image:@"tabbar_contacts" selectedImage:@"tabbar_contacts_selected"];
[self addChildVc:[[MoreViewController alloc] init] title:@"More" image:@"tabbar_more" selectedImage:@"tabbar_more_selected"];
[self addChildVc:[[ProfileViewController alloc] init] title:@"Profile" image:@"tabbar_profile" selectedImage:@"tabbar_profile_selected"];
}
- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
childVc.title = title;
childVc.tabBarItem.image = [UIImage imageNamed:image];
childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 每一个控制器都是导航控制器
UINavigationViewController *navigationVc = [[UINavigationViewController alloc] initWithRootViewController:childVc];
[self addChildViewController:navigationVc];
}
tabbar上的标题默认会直接同步到导航控制器上.
每个界面都有自己的导航控制器, 界面跳转都有自己的栈。