度娘了一圈发现基本上都是TabLayout或者其他的导航栏添加角标,所以写这篇博客记录下来。
先来看下实现的效果图:


代码也是很简单的
BottomNavigationMenuView中的每一个Tab就是一个FrameLayout,所以我们可以在上面随意添加View、这样也就可以实现我们的角标了。

//获取整个的NavigationView
BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);

//这里就是获取所添加的每一个Tab(或者叫menu),
View tab = menuView.getChildAt(3);
BottomNavigationItemView itemView = (BottomNavigationItemView) tab;

//加载我们的角标View,新创建的一个布局
View badge = LayoutInflater.from(this).inflate(R.layout.menu_badge, menuView, false);

//添加到Tab上
itemView.addView(badge);

menu_badge.xml file:
这里这个布局的大小,其实也就是每一个Tab的大小了。把显示数量的TextView水平居中,这样也就刚好在Tab的中间了(剩下就看你自己想怎么放了….)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/tv_msg_count"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_3"
android:background="@drawable/bg_red_circle_10"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/sp_12"
android:visibility="gone" />

</LinearLayout>

设置角标的数量
TextView count = (TextView) badge.findViewById(R.id.tv_msg_count);
count.setText(String.valueOf(1));

//如果没有消息,不需要显示的时候那只需要将它隐藏即可
count.setVisibility(View.GONE);

 

  1. 在点击事件中完成各个menu的点击事件,实现Fragment的替换,另外三个点击事件内容类似
// 去掉menu大于3个后的动画
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

// 导航 menu 点击事件
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
     @Override
     public boolean onNavigationItemSelected(@NonNull MenuItem item){
         switch (item.getItemId()){
             case R.id.download:
                  if(lastShowFragment!=0){
                      replaceFragment(lastShowFragment,0);
                      lastShowFragment=0;
                   }
                  break;
              case R.id.game:
                  break;
              case R.id.search:
                  break;
               case R.id.shopping:
                  break;
                }
              
              // 默认 false
              // false 的话 下面颜色不会变化
               return true;
            }
        });
  1. 在 Activity 中 的 onCreate 中完成 Fragment 数组的装填,并在 Activity 中显示第一个 Fragment
/**
* 初始化 Fragment 并在 Activity 中显示第一个 Fragment
*/
private void initFragment(){ fragments=new ArrayList<>(); for(int i=0;i<4;i++){ fragments.add(FruitFragment. newFragment()); } lastShowFragment=0; /**
* 在 Activity 中加载第一个 Fragment
*/
getSupportFragmentManager() .beginTransaction() .add(R.id.relative_layout,fragments.get(0)) .show(fragments.get(0)) .commit(); Log.d(TAG,"initFragment over"); }
  1. 根据记录最后在 Activity 中显示的 Fragment 的变量 lastShowFragment ,和 menu 需要的 Fragment 完成替换
 /**
* 替换 Activity 中的 Fragment
* @param lastShowFragment
* @param index
*/
private void replaceFragment(int lastShowFragment,int index){ FragmentTransaction transaction=getSupportFragmentManager().beginTransaction(); transaction.hide(fragments.get(lastShowFragment)); // 确认需要的 Fragment 是否已添加 if(!fragments.get(index).isAdded()){ transaction.add(R.id.relative_layout, fragments.get(index)); } transaction.show(fragments.get(index)).commitAllowingStateLoss(); Log.d(TAG,"replaceFragment lastShowFragment : "+lastShowFragment+" index : "+index); }
  1. 效果
    Screenshot_1519977714.png
Screenshot_1519977720.png
Screenshot_1519977726.png
Screenshot_1519977732.png


小结

BottomBarLayout 第三方 可实现角标

BottomNavigationViewHelper 参考博客

BottomNavigationView + Fragment 参考博客

转自:https://www.jianshu.com/p/0bdcd16c4d68

转自:https://blog.csdn.net/a_zhon/article/details/78334515

参考: https://www.jianshu.com/p/e2a8791e80d6