开篇
在开发Android应用中,为应用添加BottomNavigationBar是一件司空见惯的事情。为此,google团队在android.support.design
包中就专门提供了快速实现BottomNavigationBar的控件:BottomNavigationView,而BottomNavigationView并没有提供显示未读消息红点提示功能。本文主要讲解如何在BottomNavigationView上实现显示未读消息红点提示功能。当然,市面上很多大神开源了第三方的BottomNavigationBar框架,这里暂不展开讨论。不过这里还是推荐一个优秀的BottomNavigationBar开源项目:https://github.com/Ashok-Varma/BottomNavigation!
效果截屏
立即体验
扫描以下二维码下载体验App(从0.2.3
版本开始,体验App内嵌版本更新检测功能):
JSCKit库传送门:https://github.com/JustinRoom/JSCKit
实施步骤
在添加未读消息红点提示之前,分析BottomNavigationView源码
- 1、从构造函数着手
public BottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
...
mMenuView = new BottomNavigationMenuView(context);
...
mPresenter.setBottomNavigationMenuView(mMenuView);
...
if (a.hasValue(R.styleable.BottomNavigationView_menu)) {
inflateMenu(a.getResourceId(R.styleable.BottomNavigationView_menu, 0));
}
...
}
a、创建BottomNavigationMenuView实例:mMenuView
b、 BottomNavigationPresenter绑定mMenuView
c、 调用方法inflateMenu(int resId)
解析xml菜单文件
- 2、inflateMenu(int resId)方法:
public void inflateMenu(int resId) {
mPresenter.setUpdateSuspended(true);
getMenuInflater().inflate(resId, mMenu);
mPresenter.setUpdateSuspended(false);
mPresenter.updateMenuView(true);
}
从方法字面上不难看出updateMenuView就是用来更新菜单视图的。
- 3、updateMenuView(boolean cleared)方法:
@Override
public void updateMenuView(boolean cleared) {
if (mUpdateSuspended) return;
if (cleared) {
mMenuView.buildMenuView();
} else {
mMenuView.updateMenuView();
}
}
它调用了mMenuView.buildMenuView()
构建菜单视图,而mMenuView
就是在BottomNavigationView构造函数中BottomNavigationPresenter绑定的BottomNavigationMenuView
的实例。
- 4、buildMenuView()方法:
public void buildMenuView() {
...
for (int i = 0; i < mMenu.size(); i++) {
mPresenter.setUpdateSuspended(true);
mMenu.getItem(i).setCheckable(true);
mPresenter.setUpdateSuspended(false);
BottomNavigationItemView child = getNewItem();
mButtons[i] = child;
child.setIconTintList(mItemIconTint);
child.setTextColor(mItemTextColor);
child.setItemBackground(mItemBackgroundRes);
child.setShiftingMode(mShiftingMode);
child.initialize((MenuItemImpl) mMenu.getItem(i), 0);
child.setItemPosition(i);
child.setOnClickListener(mOnClickListener);
addView(child);
}
}
到这里,我们不难看出,每一个menu就是一个BottomNavigationItemView示例:
public class BottomNavigationItemView extends FrameLayout implements MenuView.ItemView {
}
所以,整个流程看下来,我们知道:
BottomNavigationView添加了一个BottomNavigationMenuView实例,而BottomNavigationMenuView实例添加了N个BottomNavigationItemView实例。
很明显,我们要给每个menu添加未读消息红点提示其实就是在BottomNavigationItemView实例上添加一个显示未读消息的view。
在BottomNavigationItemView上添加未读消息红点提示view
- 1、找到BottomNavigationMenuView:
private BottomNavigationView navigation;
BottomNavigationMenuView menuView = null;
for (int i = 0; i < navigation.getChildCount(); i++) {
View child = navigation.getChildAt(i);
if (child instanceof BottomNavigationMenuView) {
menuView = (BottomNavigationMenuView) child;
break;
}
}
- 2、找到BottomNavigationItemView并添加未读消息红点view
if (menuView != null) {
int dp8 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
dotViews = new DotView[menuView.getChildCount()];
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView.LayoutParams params = new BottomNavigationItemView.LayoutParams(i == menuView.getChildCount() - 1 ? dp8 : dp8 * 2, 0);
params.gravity = Gravity.CENTER_HORIZONTAL;
params.leftMargin = dp8 * 3;
params.topMargin = dp8 / 2;
BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
DotView dotView = new DotView(this);
itemView.addView(dotView, params);
if (i < menuView.getChildCount() - 1) {
dotView.setUnReadCount(new Random().nextInt(20));
}
dotViews[i] = dotView;
}
}
运行后看效果。
篇尾
原创不易,给个爱心,谢谢!QQ:1006368252。
勿问成功的秘诀为何,且尽全力做你应该做的事吧。——美华纳
网友评论