Android底部导航栏的实现方式这里主要总结了3种,代码尽量追求精简,可以直接拷贝使用,便于大家比较选择。
1.BottomNavigationView实现底部导航栏
<1>首先在gradle文件中添加依赖,implementation'com.android.support:design:26.1.0',注意该依赖的版本不要高于compileSDKVersion,否则会报错。
<2>在res目录下新建menu文件夹,创建bottom_view.xml,也就是我们底部tab的样式,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/item_news"
android:icon="@drawable/ic_account_balance_black_24dp"
android:title="首页" />
<item
android:id="@+id/item_lib"
android:icon="@drawable/ic_card_giftcard_black_24dp"
android:title="礼物" />
<item
android:id="@+id/item_find"
android:icon="@drawable/ic_account_box_black_24dp"
android:title="个人" />
<item
android:id="@+id/item_more"
android:icon="@drawable/ic_alarm_add_black_24dp"
android:title="设置" />
</menu>
这里需要注意的是,当item个数在3个和三个以内时,点击tab的效果没有问题,但是如果是4个和四个以上的话,点击tab会出现一个错位的动画,视觉效果非常不好。这个错位的效果我们使用反射把它去掉了。
<3>activity中引入我们的bottom_view.xml,代码如下:
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_navigation" />
<!-- app:itemBackground="@color/white"被删除后水波纹就出来了,原因呢?-->
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemIconTint="@drawable/bottom_navigation_selector"
app:itemTextColor="@drawable/bottom_navigation_selector"
app:menu="@menu/bottom_view"/>
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_above="@id/bottom_navigation"
android:background="@drawable/bottom_shadow" />
上面的布局文件中,item_background是用来设置整个底部的背景色的,这里没有使用。itemIconTint是用来设置图片在默认状态和点击后图片的颜色变化,itemTextColor是用来设置文字在默认状态和点击后颜色的变化,我们统一使用自定义的selector即可。View中添加了背景bottom_shadow,在Item点击后会出现水波纹效果,其实,我有点不理解,bottom_shadow是添加给了VIew,那点击Item的时候为什么会出现水波纹效果呢?知道的同学请留言,不胜感激。
<4>activity中的代码处理如下:
public class BottomNavigationViewActivity extends AppCompatActivity {
private Button button;
private MenuItem lastItem; // 上一个选中的item
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
public void initView(){
viewPager=findViewById(R.id.viewpager);
final BottomNavigationView view=(BottomNavigationView)findViewById(R.id.bottom_navigation);
//默认 >3 的选中效果会影响ViewPager的滑动切换时的效果,故利用反射去掉
BottomNavigationViewHelper.disableShiftMode(view);
//拿到默认选中的item
lastItem=view.getMenu().getItem(0);
//点击选择item
view.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.item_news:
viewPager.setCurrentItem(0);
break;
case R.id.item_lib:
viewPager.setCurrentItem(1);
break;
case R.id.item_find:
viewPager.setCurrentItem(2);
break;
case R.id.item_more:
viewPager.setCurrentItem(3);
break;
}
return false;
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (lastItem != null) {
lastItem.setChecked(false);
} else {
view.getMenu().getItem(0).setChecked(false);
}
lastItem= view.getMenu().getItem(position);
lastItem.setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
//禁止ViewPager滑动的话,就将这里的注释取消掉
// viewPager.setOnTouchListener(new View.OnTouchListener() {
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// return true;
// }
// });
setupViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new HomeFragment());
adapter.addFragment(new GiftFragment());
adapter.addFragment(new PersonFragment());
adapter.addFragment(new SettingFragment());
viewPager.setAdapter(adapter);
}
}
我们可以看一下不使用反射时实现的效果图:
使用反射后最终实现的效果图如下:
源码提供:https://download.csdn.net/download/qq_27640531/10367120 这里说明下,系统默认下载最低2积分,所以无法免费下载,没有积分的可以直接找我拿代码,微信18518213807
总结:<1>底部Item的点击水波纹效果是在布局文件中定义了View并设置背景bottom_shadow实现的
<2>通过反射机制取消四个及四个以上item时,点击item出现的错位动画效果
<3>通过ItemIconTint和ItemTextColor设置了图片和文字的切换效果,自定义selector
<4>结合ViewPager实现页面切换。
原文参考地址:https://www.jianshu.com/p/0ba25cc65889#
2.使用开源框架LuseenBottomNavigation,github地址:https://github.com/armcha/LuseenBottomNavigation
首先我们在gradle文件中,添加对LuseenBottomNavigation的引用:implementation 'com.github.armcha:LuseenBottomNavigation:1.8.2'
之后在我们的布局文件中直接添加即可,代码如下:
<com.luseen.luseenbottomnavigation.BottomNavigation.BottomNavigationView
app:bnv_active_color="@color/three"
app:bnv_shadow="false"
android:id="@+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
LuseenBottomNavigation默认会在底部导航的布局上面再加一个阴影区域,这样能隔开底部导航栏和实际展示内容,bnv_shadow="false"是默认开启,true的话会关闭这个阴影的显示。画的有点歪歪扭扭,但是大致就在这个绿线的位置。
之后我们在代码中,添加item,这里不同于上面BottomNavigationVIew的实现,无论添加多少个Item不会再出现切换时的偏移动画效果了。
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigation);
BottomNavigationItem bottomNavigationItem = new BottomNavigationItem
("Record", ContextCompat.getColor(this, R.color.one), R.drawable.ic_accessibility_black_24dp);
BottomNavigationItem bottomNavigationItem1 = new BottomNavigationItem
("Like", ContextCompat.getColor(this, R.color.two), R.drawable.ic_alarm_black_24dp);
BottomNavigationItem bottomNavigationItem2 = new BottomNavigationItem
("what", ContextCompat.getColor(this, R.color.three), R.drawable.ic_accessibility_black_24dp);
BottomNavigationItem bottomNavigationItem3 = new BottomNavigationItem
("jiush", ContextCompat.getColor(this, R.color.four), R.drawable.ic_account_balance_black_24dp);
bottomNavigationView.addTab(bottomNavigationItem);
bottomNavigationView.addTab(bottomNavigationItem1);
bottomNavigationView.addTab(bottomNavigationItem2);
bottomNavigationView.addTab(bottomNavigationItem3);
这里的R.color.one,R.color.two等都是我们自定义的颜色,在点击item时背景色会切换成对应的颜色。
实现的效果如下:
这种效果很动画,但是有时候过于花哨,所以有可能会取消这个背景色替换,并要求图片和文字变成我们需要的颜色:所以我们首先在布局文件BottomNavigationView下添加如下属性:
app:bnv_active_color="@color/three"
也就是图片和文字被选中时的颜色。并在代码中取消item切换时的背景色替换效果。
bottomNavigationView.isColoredBackground(false);
有时候,我们可能希望只让被选中的item显示底部文字,那么只需要在布局文件BottomNavigationView下添加如下属性即可:
app:bnv_with_text="false"
效果如下:
具体的调用方式,github中给的比较清楚,这里就不做赘述了,感兴趣的同学可以去github研究下:https://github.com/armcha/LuseenBottomNavigation
其实这种实现方式应该是最精简和推荐的,后面我再把ViewPager切换界面的部分补上。
3:SlidingTabLayout实现底部导航栏
我凑,我看了下以前写的代码,真啰嗦,想要看的直接百度或者管我要代码吧,就是这样。