第一种用radiobutton实现

https://wizardforcel.gitbooks.io/w3school-android/content/75.html

布局文件,使用radiogroup

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/ly_top_bar"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorPrimary"/> <RadioGroup
android:layout_width="match_parent"
android:layout_height="56dp"
android:id="@+id/rg_tab_bar"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rbb_1"
style="@style/tab_menu_item"
android:drawableTop="@drawable/qq"
android:text="@string/jihua"/>
<RadioButton
android:id="@+id/rbb_2"
style="@style/tab_menu_item"
android:drawableTop="@drawable/pp"
android:text="@string/dating"/>
<RadioButton
android:id="@+id/rbb_3"
style="@style/tab_menu_item"
android:drawableTop="@drawable/oo"
android:text="@string/wode"/>
</RadioGroup> <View
android:id="@+id/div_tab_bar"
android:layout_width="match_parent"
android:layout_height="2px"
android:layout_above="@id/rg_tab_bar" /> <FrameLayout
android:id="@+id/ly_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/div_tab_bar"
android:layout_below="@id/ly_top_bar"> </FrameLayout> </RelativeLayout>

activity文件,每个界面是一个fragment

package com.example.administrator.miaomiao;

import android.graphics.drawable.Drawable;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup; public class allactivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
private RadioGroup rg_tab_bar;
private RadioButton rb_1;
private RadioButton rb_2;
private RadioButton rb_3; //Fragment Object
private Fragment1 fg1;
private Fragment2 fg2;
private Fragment3 fg3;
private FragmentManager fManager;
// private Toolbar toolbar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_allactivity);
fManager = getSupportFragmentManager();
rg_tab_bar = (RadioGroup) findViewById(R.id.rg_tab_bar);
rg_tab_bar.setOnCheckedChangeListener(this);
//获取第一个单选按钮,并设置其为选中状态
rb_1 = (RadioButton) findViewById(R.id.rbb_1);
rb_2 = (RadioButton) findViewById(R.id.rbb_2);
rb_3 = (RadioButton) findViewById(R.id.rbb_3);
rb_1.setChecked(true);
initView();
} @Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
FragmentTransaction fTransaction = fManager.beginTransaction();
hideAllFragment(fTransaction);
switch (checkedId){
case R.id.rbb_1:
if(fg1 == null){
fg1 = new Fragment1();
fTransaction.add(R.id.ly_content,fg1, "Fragment1");
}else{
fTransaction.show(fg1);
}
break;
case R.id.rbb_2:
if(fg2 == null){
fg2 = new Fragment2();
fTransaction.add(R.id.ly_content,fg2, "Fragment2");
}else{
fTransaction.show(fg2);
}
break;
case R.id.rbb_3:
if(fg3 == null){
fg3 = new Fragment3();
fTransaction.add(R.id.ly_content,fg3, "Fragment3");
}else{
fTransaction.show(fg3);
}
break;
}
fTransaction.commit();
} //隐藏所有Fragment
private void hideAllFragment(FragmentTransaction fragmentTransaction){
if(fg1 != null)fragmentTransaction.hide(fg1);
if(fg2 != null)fragmentTransaction.hide(fg2);
// if(fg3 != null)fragmentTransaction.hide(fg3);
if(fg3 != null)fragmentTransaction.hide(fg3);
} private void initView() {
//定义底部标签图片大小和位置
Drawable drawable_news = getResources().getDrawable(R.drawable.qq);
//当这个图片被绘制时,给他绑定一个矩形 ltrb规定这个矩形
drawable_news.setBounds(, , , );
//设置图片在文字的哪个方向
rb_1.setCompoundDrawables(null, drawable_news, null, null); //定义底部标签图片大小和位置
Drawable drawable_live = getResources().getDrawable(R.drawable.pp);
//当这个图片被绘制时,给他绑定一个矩形 ltrb规定这个矩形
drawable_live.setBounds(, , , );
//设置图片在文字的哪个方向
rb_2.setCompoundDrawables(null, drawable_live, null, null); //定义底部标签图片大小和位置
Drawable drawable_tuijian = getResources().getDrawable(R.drawable.oo);
//当这个图片被绘制时,给他绑定一个矩形 ltrb规定这个矩形
drawable_tuijian.setBounds(, , , );
//设置图片在文字的哪个方向
rb_3.setCompoundDrawables(null, drawable_tuijian, null, null); } }

第二种在github上搜的,博客地址为https://www.jianshu.com/p/ce8e09cda486

因为公司好多项目会用到底部导航栏,大都千篇一律,无非2-5个Tab(可能会有些点击动画、红点提示或者中间多个加号)总是重复相同的操作...所以...很懒的我希望几行代码就能实现这个效果(少敲一行是一行)

效果图

 
轻松实现.gif

实现

  • 依赖

Step 1. Add it in your root build.gradle at the end of repositories:

    allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}

Step 2. Add the dependency

    implementation 'com.github.forvv231:EasyNavigation:1.0.3'
1、基础版

xml

<com.next.easynavigation.view.EasyNavigationBar
android:id="@+id/navigationBar"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.next.easynavigation.view.EasyNavigationBar>

注:因EasyNavigationBar包含ViewPager,需设置充满

Activity

private String[] tabText = {"首页", "发现", "消息", "我的"};
//未选中icon
private int[] normalIcon = {R.mipmap.index, R.mipmap.find, R.mipmap.message, R.mipmap.me};
//选中时icon
private int[] selectIcon = {R.mipmap.index1, R.mipmap.find1, R.mipmap.message1, R.mipmap.me1}; private List<android.support.v4.app.Fragment> fragments = new ArrayList<>();
navigationBar = findViewById(R.id.navigationBar);

fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new FirstFragment());
fragments.add(new SecondFragment()); navigationBar.titleItems(tabText)
.normalIconItems(normalIcon)
.selectIconItems(selectIcon)
.fragmentList(fragments)
.fragmentManager(getSupportFragmentManager())
.build();

怎么样 是不是很Easy啊( ̄▽ ̄)~*

2、加号版本
private String[] tabText = {"首页", "发现", "", "消息", "我的"};
//未选中icon
private int[] normalIcon = {R.mipmap.index, R.mipmap.find, R.mipmap.add_image, R.mipmap.message, R.mipmap.me};
//选中时icon
private int[] selectIcon = {R.mipmap.index1, R.mipmap.find1, R.mipmap.add_image, R.mipmap.message1, R.mipmap.me1};
navigationBar.titleItems(tabText)
.normalIconItems(normalIcon)
.selectIconItems(selectIcon)
.fragmentList(fragments)
.mode(EasyNavigationBar.MODE_ADD)
.fragmentManager(getSupportFragmentManager())
.build();
  • 资源数组中添加文字和图片,不需要文字可传空串
  • mode设置为EasyNavigationBar.MODE_ADD
 
基础版和加号版本.png
3、中间添加自定义view
 View view = LayoutInflater.from(this).inflate(R.layout.custom_add_view, null);

 navigationBar.titleItems(tabText)
.normalIconItems(normalIcon)
.selectIconItems(selectIcon)
.fragmentManager(getSupportFragmentManager())
.fragmentList(fragments)
.mode(EasyNavigationBar.MODE_ADD_VIEW)
.addCustomView(view)
.addLayoutRule(EasyNavigationBar.RULE_CENTER)
.build();
  • addCustomView添加自定义好的view
  • mode设置为EasyNavigationBar.MODE_ADD_VIEW

     
    自定义中间按钮

属性

  • 什么?不过瘾?看看下面给你提供可以更改的属性,满足你的需求(xml也可设置)
navigationBar.titleItems(tabText)      //必传  Tab文字集合
.normalIconItems(normalIcon) //必传 Tab未选中图标集合
.selectIconItems(selectIcon) //必传 Tab选中图标集合
.fragmentList(fragments) //必传 fragment集合
.fragmentManager(getSupportFragmentManager()) //必传
.iconSize(20) //Tab图标大小
.tabTextSize(10) //Tab文字大小
.tabTextTop(2) //Tab文字距Tab图标的距离
.normalTextColor(Color.parseColor("#666666")) //Tab未选中时字体颜色
.selectTextColor(Color.parseColor("#333333")) //Tab选中时字体颜色
.scaleType(ImageView.ScaleType.CENTER_INSIDE) //同 ImageView的ScaleType
.navigationBackground(Color.parseColor("#80000000")) //导航栏背景色
.onTabClickListener(new EasyNavigationBar.OnTabClickListener() { //Tab点击事件 return true 页面不会切换
@Override
public boolean onTabClickEvent(View view, int position) {
return false;
}
})
.smoothScroll(false) //点击Tab Viewpager切换是否有动画
.canScroll(false) //Viewpager能否左右滑动
.mode(EasyNavigationBar.MODE_ADD) //默认MODE_NORMAL 普通模式 //MODE_ADD 带加号模式
.anim(Anim.ZoomIn) //点击Tab时的动画
.addIconSize(36) //中间加号图片的大小
.addLayoutHeight(100) //包含加号的布局高度 背景透明 所以加号看起来突出一块
.navigationHeight(40) //导航栏高度
.lineHeight(100) //分割线高度 默认1px
.lineColor(Color.parseColor("#ff0000"))
.addLayoutRule(EasyNavigationBar.RULE_BOTTOM) //RULE_CENTER 加号居中addLayoutHeight调节位置 EasyNavigationBar.RULE_BOTTOM 加号在导航栏靠下
.addLayoutBottom(10) //加号到底部的距离
.hasPadding(true) //true ViewPager布局在导航栏之上 false有重叠
.hintPointLeft(-3) //调节提示红点的位置hintPointLeft hintPointTop(看文档说明)
.hintPointTop(-3)
.hintPointSize(6) //提示红点的大小
.msgPointLeft(-10) //调节数字消息的位置msgPointLeft msgPointTop(看文档说明)
.msgPointTop(-10)
.msgPointTextSize(9) //数字消息中字体大小
.msgPointSize(18) //数字消息红色背景的大小
.addAlignBottom(true) //加号是否同Tab文字底部对齐 RULE_BOTTOM时有效;
.addTextTopMargin(50) //加号文字距离加号图片的距离
.addTextSize(15) //加号文字大小
.addNormalTextColor(Color.parseColor("#ff0000")) //加号文字未选中时字体颜色
.addSelectTextColor(Color.parseColor("#00ff00")) //加号文字选中时字体颜色
.build();

需求(简单列举几个)

需求1:红点或数字消息提示
//数字消息大于99显示99+ 小于等于0不显示,取消显示则可以navigationBar.setMsgPointCount(2, 0)
navigationBar.setMsgPointCount(2, 109);
navigationBar.setMsgPointCount(0, 5);
//红点提示 第二个参数控制是否显示
navigationBar.setHintPoint(3, true);

清除也可以这样(这样的方法名可能直观些)

//清除第四个红点提示
navigationBar.clearHintPoint(3);
//清除第一个数字消息
navigationBar.clearMsgPoint(0);

数字消息的位置可通过msgPointLeft、msgPointTop来控制,默认这两个值为Tab图标的一半

 
数字消息位置属性说明.png

注:红点提示同理,通过hintPointLeft和hintPointTop两个属性调节位置

需求2:半开放式登录、点击“我的”Tab、不切换页面、需要进行登录操作
  .onTabClickListener(new EasyNavigationBar.OnTabClickListener() {
@Override
public boolean onTabClickEvent(View view, int position) {
if (position == 3) {
Toast.makeText(AddActivity.this, "请先登录", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
})

onTabClickEvent方法中return true则拦截事件、不进行页面切换

注:这种情况canScroll不能设置为true、否则滑动仍会切换页面

需求3:加号突出(以前这种比较多,现在好多都在导航栏里面、找了好多app...)
 
简书和爱奇艺两种加号.png
  • 像图中的两种需求,如何调整加号的位置呢

提供两种解决方式、addLayoutRule设置属性RULE_CENTER和RULE_BOTTOM两种

 
新建位图图像 (2).png

1、RULE_CENTER
中间加号(红色圆圈)相对红色框居中,可通过addLayoutHeight调节加号的位置,此时addLayoutBottom属性无效

2、RULE_BOTTOM
中间加号(红色圆圈)在红色框底部,可通过addLayoutBottom属性调节加号到底部的距离,从而改变加号的位置;

 <com.next.easynavigation.view.EasyNavigationBar
android:id="@+id/navigationBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:Easy_addIconSize="40dp"
app:Easy_navigationHeight="60dp"
app:Easy_addLayoutHeight="80dp"
app:Easy_addLayoutBottom="10dp"
app:Easy_addLayoutRule="RULE_CENTER">
  • 中间加号下面文字和其他Tab文字对齐

addAlignBottom属性可设置加号文字和其他Tab底部对齐。
注:addLayoutRule= RULE_BOTTOM时、addAlignBottom才有效

 
类似全民k歌.jpg
需求4:加号旋转
  • EasyNavigationBar.MODE_ADD模式下

可使用 navigationBar.getAddImage()获取到加号直接进行操作;

  • EasyNavigationBar.MODE_ADD_VIEW模式下

可使用navigationBar.getCustomAddView()对你添加的view进行操作;

navigationBar.getCustomAddView().animate().rotation(180).setDuration(400);
需求5:点击第一个页面中的按钮、跳转到第二个页面并执行其中的方法(部分人可选择无视)

第二个页面添加方法供Activity调用

 //提示消息
public void showToast(String str) {
Toast.makeText(getActivity(), str, Toast.LENGTH_SHORT).show();
}

第一个页面中调用代码

 //跳转第二个页面
((AddActivity) getActivity()).getNavigationBar().selectTab(1);
//调用第二个页面的方法
((SecondFragment) (((AddActivity) getActivity()).getNavigationBar().getAdapter().getItem(1))).showToast("嘻嘻哈哈嗝");

使用注意事项

若运行后EasyNavigationBar为空白、则查看Log信息提示修改

  • EasyNavigationBar.MODE_ADD模式下

中间图片资源及文字同其他tab一起传入,若不需要文字、传空串即可,三个资源数组数量应该相等且数量应为奇数(因为有加号存在)。

若想点击加号实现Fragment切换,addAsFragment设置为true、此时Fragment数量=资源数量

若点击加号不切换Fragment,跳转界面或弹出底部菜单(此时加号文字图片状态不会变),addAsFragment应为false(默认false),此时Fragment数量=资源数量-1

  • EasyNavigationBar.MODE_ADD_VIEW模式下

若想点击加号实现Fragment切换,addAsFragment设置为true、此时Fragment数量=资源数量+1

若点击加号不切换Fragment,addAsFragment应为false(默认false),实现跳转界面或弹出底部菜单(此时),FragmentFragment数量=资源数量


更新(1.0.0)

1、中间加号下可添加文字;
2、中间加号位置可添加自定义View;
3、可设置点击加号后同其他Tab一样切换Fragment;

  • 移除addIcon属性、添加中间的图片文字同Tab一样
  • 移除onAddClickListener、监听事件同Tab、实现onTabClickListener
  • 新增addAlignBottom属性(加号是否同Tab文字底部对齐 RULE_BOTTOM时有效)
  • 新增addTextTopMargin属性(加号文字距离加号图片的距离)
  • 新增addTextSize属性(加号文字大小)
  • 新增addNormalTextColor属性(加号文字未选中时字体颜色)
  • 新增addSelectTextColor属性(加号文字选中时字体颜色)
  • 更改addIconBottom方法名为addLayoutBottom
  • 更改addIconRule方法名为addLayoutRule

Demo

github:https://github.com/forvv231/EasyNavigation

apk:https://fir.im/7r4d


By the way

  • 本Demo中仿微博弹出菜单实现

参考https://github.com/DuShuYuan/PlusMenu

android底部导航栏实现的更多相关文章

  1. Android底部导航栏——FrameLayout + RadioGroup

    原创文章,转载请注明出处http://www.cnblogs.com/baipengzhan/p/6285881.html Android底部导航栏有多种实现方式,本文详细介绍FrameLayout ...

  2. Android底部导航栏创建——ViewPager + RadioGroup

    原创文章,引用请注明出处:http://www.cnblogs.com/baipengzhan/p/6270201.html Android底部导航栏有多种实现方式,本文详解其中的ViewPager ...

  3. Android底部导航栏

    Android底部导航栏 今天简单写了一个底部导航栏,封装了一个库,用法比较简单 效果图 Github地址:https://github.com/kongqw/KqwBottomNavigation ...

  4. Android底部导航栏(可滑动)----TabLayout+viewPager

    [TabLayout] ①TabLayout是选项卡,在屏幕空间有限的情况下,对不同的空间进行分组.属于android support design,更多的用于新闻上,如果放在底部也可做底部导航栏 ② ...

  5. Android 底部导航栏实现一 Fragment-replace

    [效果](这里下载的软件收费的试用有水印) [推荐]这里推荐一个图标网http://iconfont.cn/.以上图标来自此图标网 [项目结构] [步骤] ①创建布局文件,写底部导航栏 <?xm ...

  6. android底部导航栏小结

    android自带的有TabHost,但好像无法满足要求, 本文只记录使用 TabLayout + Fragment  和 android 自带的 BottomNavigationView + Fra ...

  7. Android 底部导航栏的xml

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&q ...

  8. Android 五种方式实现Android底部导航栏

    https://segmentfault.com/a/1190000007697941

  9. Android应用底部导航栏(选项卡)实例

    现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其 ...

随机推荐

  1. git内容补充-Git零基础快速入门-苏玲

    https://git-scm.com/book/zh/v2 git历史 集中式版本控制管理:cvs.svn 分布式版本控制管理:git 基本命令 git config --list --global ...

  2. 《操作系统真象还原》bochs安装

    在安装bochs之前,我们先需要安装虚拟机和linux发行版,也可以安装双系统,总之有个linux操作系统就好. 我是在ubuntu14.04系统下安装bochs的. 安装Bochs 以下为安装步骤 ...

  3. ABC155 D pair 边界处理取整

    ABC155 D pair 取整坑点 思路 很常见的一道题,二分找答案,然后看这个答案排rank?,排rank?用二分继续找一遍二分套二分即可,就是边界比较烦,老年人写的心情烦躁 老年人被取整坑的几天 ...

  4. numpy学习(五)

    练习篇(Part 5) 51. Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆) ar ...

  5. linux上部署springboot应用的脚本

    #!/bin/bash #getProcessId then kill pids=$(ps -ef | grep flashsale| awk '{print $2}') for pid in $pi ...

  6. pandas模块详解

    Pandas模块 1.什么是pandas pandas是基于numpy构建的,用来做数据分析的 2.pandas能干什么 具备对其功能的数据结构DataFrame,Series 集成时间序列功能 提供 ...

  7. [JSOI2016]最佳团体 DFS序/树形DP

    题目 洛谷 P4322 [JSOI2016]最佳团体 Description 茜茜的舞蹈团队一共有\(N\)名候选人,这些候选人从\(1\)到\(N\)编号.方便起见,茜茜的编号是\(0\)号.每个候 ...

  8. Mike and strings

    Mike has n strings s1, s2, ..., sn each consisting of lowercase English letters. In one move he can ...

  9. redhat 桌面系统配置

    1.grouplist命令 yum grouplist 回车 2.  yum groupinstall "GNOME Desktop" "Graphical Admini ...

  10. Learn from Niu 2020.1.13

    观念: 1. 把可视化的东西拾起来, 毕竟是做那个出身的. 2. 可视化里面时序数据,时空数据一直都是非常重要的. 3. know your data永远是最重要的一步, 我想更好的方式是,数据驱动, ...