微信下方导航栏我的最简单实现
一、概述
因为公司项目的下方导航栏太普通了,想着仿照微信的导航栏做个效果。
二、思考
据我观察,我们可以通过有色图(选中项显示效果)叠在灰色图(未选中项显示效果),然后通过改变有色图的透明度来实现效果。
1、肯定要监听这个过程,
2、根据这个过程变化图片与文本颜色。
监听这个过程
因为是我用的是上面ViewPager+下面LinearLayout里面4个RelativeLayout来实现的导航栏效果。所以要监听OnPageChangeListener的onPageScrolled。
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
根据这个过程变化图片与文本颜色
观察里面的参数有三个,这里有点坑,害我走了点弯路,一开始我以为其中position是当前页面下标(其实不是)。因为我要监听滑动的过程,自然而然就没去理会这个参数。positionOffset是一个进度值,手指向右滑动这个值从1趋向0,手指向左滑动这个值从0趋向1,然后突变为0(突变的时候position也会相应变更了,所以放心,这个突变并不影响我们的实现).positionOffsetPixels是一个像素值,变化情况可以类比positionOffset。
这里是弯路思考可以忽略(也可以实现,但比较复杂):
这里理所当然的选择了positionOffset
这个过程中首先我得提供当前要变化的是导航栏的哪两个item,以及分别变化的值。
但是由于进度值的变化都在0到1这个区间,无法单单通过当前值来得到当前画面是在左侧还是右侧,无法得知要改变的是哪两个item。所以我们通过保存上一个positionOffset来比较当前positionOffset,获得当前变化是变大(手指向左滑动)还是变小(手指向右滑动)。
开始positionOffset变小,则记录在左侧;-》变化当前item和左侧item,根据positionOffset变化透明度
开始positionOffset变大,则记录在右侧;-》变化当前item和右侧item,根据positionOffset变化透明度
在左侧positionOffset变大,且positionOffset突变(差值大于0.5f),则记录在右侧;-》变化当前和右
在右侧positionOffset变小,且positionOffset突变(差值大于0.5f),则记录在左侧;-》变化当前和左
其实position并不是当前页面下标,它的变化规律为是,当前页面手指向右滑动,position为左侧页面下标。当前页面手指向左滑动,position为当前页面下标。没有具体去看源码,但是我是这样理解的,它这个坐标指的是当前显示页面的第一个页面所在的下标(滑动的时候会显示两个页面,也就是左侧这个页面的下标,停止滑动的时候只会显示一个页面,当前页面也就是最左侧的页面了,也就是当前页面的下标了),通过position我们就能知道当前要变化的是哪两个item,然后通过positionOffset,变化item的透明度实现效果。
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
switch (viewPager.getCurrentItem()) {
//在第一个页面
case 0:
//在右侧
rlyIndexP.setAlpha(1.0f - positionOffset);
rlyDeviceP.setAlpha(positionOffset);
break;
//在第二个页面
case 1:
//在左侧
if (position == 0) {
rlyIndexP.setAlpha(1.0f - positionOffset);
rlyDeviceP.setAlpha(positionOffset);
} else {
//在右侧
rlyDeviceP.setAlpha(1.0f - positionOffset);
rlyShopP.setAlpha(positionOffset);
}
break;
//在第三个页面
case 2:
//在左侧
if (position == 1) {
rlyDeviceP.setAlpha(1.0f - positionOffset);
rlyShopP.setAlpha(positionOffset);
} else {
//在右侧
rlyShopP.setAlpha(1.0f - positionOffset);
rlyMeP.setAlpha(positionOffset);
}
break;
//在第四个页面
case 3:
//在左侧
if (position == 2) {
rlyShopP.setAlpha(1.0f - positionOffset);
rlyMeP.setAlpha(positionOffset);
}
break;
}
}
@Override
public void onPageSelected(int position) {
ChangeImageBg(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
private void ChangeImageBg(int index) {
rlyIndexP.setAlpha(index == SELECTED_INDEX ? 1.0f : 0.0f);
rlyDeviceP.setAlpha(index == SELECTED_DEVICE ? 1.0f : 0.0f);
rlyShopP.setAlpha(index == SELECTED_SHOW ? 1.0f : 0.0f);
rlyMeP.setAlpha(index == SELECTED_ME ? 1.0f : 0.0f);
}