为了实现顶部导航栏和viewpager的关联,我用了一种拙劣的方式:通过设置viewpager的OnPageChangeListener,监听viewpager变化来改变导航栏的图标状态。
其中,导航栏用一个LinearLayout包裹三个ImageView实现。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#fff"
android:elevation="1dp">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:layout_centerInParent="true"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:id="@+id/analysisIndicator"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:src="@drawable/ic_assessment_black_48dp"
android:tint="@color/indicatorNoSelect"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:layout_centerInParent="true"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:id="@+id/recordIndicator"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:src="@drawable/ic_mode_edit_black_48dp"
android:tint="@color/indicatorSelected"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:layout_centerInParent="true"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:id="@+id/queryIndicator"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:src="@drawable/ic_search_black_48dp"
android:tint="@color/indicatorNoSelect"/>
</RelativeLayout>
</LinearLayout>
ViewPager就普通的。
实现:
- 颜色的改变,就用Color.rgb(int r, int g, int b)来动态获取,这里的动态和这个滑动中时刻改变的positionOffset关联,positionOffset是偏移百分比,是OnPageScrolled的第二个参数。OnPageScrolled有三个参数,分别是,当前位置position,偏移百分比positionOffset,偏移像素positionOffsetPixels
public static void changeTintByOffset(ImageView fromView, ImageView toView, float positionoffset){
fromView.setImageTintList(ColorStateList.valueOf(blendColor(COLOR_INDICATOR_DARK, COLOR_INDICATOR_LIGHT, positionoffset)));
toView.setImageTintList(ColorStateList.valueOf(blendColor(COLOR_INDICATOR_LIGHT, COLOR_INDICATOR_DARK, positionoffset)));
}
private static int blendColor(int toColor, int fromColor, float positionoffset){
final float inverseRation = 1f - positionoffset;
float r = (Color.red(toColor) * positionoffset) + (Color.red(fromColor) * inverseRation);
float g = (Color.green(toColor) * positionoffset) + (Color.green(fromColor) * inverseRation);
float b = (Color.blue(toColor) * positionoffset) + (Color.blue(fromColor) * inverseRation);
return Color.rgb((int) r, (int) g, (int) b);
}
private static ColorStateList getColorStateListByColor(int color){
return ColorStateList.valueOf(color);
}
- 为导航添加点击跳转效果
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.analysisIndicator:
isClickChange = true;
targetPage = 0;
viewPager.setCurrentItem(0, true);
break;
case R.id.recordIndicator:
isClickChange = true;
targetPage = 1;
viewPager.setCurrentItem(1, true);
break;
case R.id.queryIndicator:
isClickChange = true;
targetPage = 2;
viewPager.setCurrentItem(2, true);
break;
}
}
- 这样子有个问题,就是点击跳转的时候,跨页面跳转的情况下,中间页面的导航指示会有渐变的变亮变暗效果,这是我不想要的,解决它只需要设置一个isClickChange,指明这是点击跳转,还需要设置一个target,当target等于viewPager.getCurrtentItem的时候,isClickChange取反
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(!isClickChange){
if(positionOffsetPixels < 0){ // to left
getfromAndtoView(position, true);
TintUtil.changeTintByOffset(fromView, toView, positionOffset);
Log.e("", positionOffsetPixels + "<<<<<<<<<<");
}
else if(positionOffsetPixels > 0){ //to right
getfromAndtoView(position, false);
TintUtil.changeTintByOffset(fromView, toView, positionOffset);
Log.e("", positionOffsetPixels + ">>>>>>>>");
}
}
}
@Override
public void onPageSelected(int position) {
changeIndicator(position);
}
@Override
public void onPageScrollStateChanged(int state) {
if(state == 0 && targetPage == viewPager.getCurrentItem()){
isClickChange = false;
Toast.makeText(MainActivity.this, viewPager.getCurrentItem() + "", Toast.LENGTH_SHORT).show();
targetPage = -1;
}
}
});
不知为何,positionOffset理应是正数,左滑递减至0,右滑由0递增,不过我这样写也达到了自己想要的效果,应该是页面数只有3个的原因,以后再来看是为什么了。
最终效果,滑动渐变,点击跳转: