您的位置:首页 > 移动开发 > Android开发

Android ViewPager 和PageTransformer滑动颜色渐变

2017-02-15 23:17 513 查看
具体效果图如下:



学习了一下PageTransformer,这个类在ViewPager页面滚动时被调用,适用于ViewPager中的itemview有动画的场景。下面是API中关于PageTransformer的介绍

A PageTransformer is invoked whenever a visible/attached page is scrolled. This offers an opportunity for the application to apply a custom transformation to the page views using animation properties.
当可见或者绑定的页面滚动时PageTransformer会被回调,这为应用中页面的views使用动画属性时来实现自定义转换提供方式(机会)。
As property animation is only supported as of Android 3.0 and forward, setting a PageTransformer on a ViewPager on earlier platform versions will be ignored.
由于属性动画仅支持3.0和3.0以上版本,因此在viewpager中3.0以下的版本PageTransformer 将被忽略。(也就是PageTransformer 仅支持在3.0以上版本中使用)


PageTransformer为接口,其中有一个方法需要我们实现就是 transformPage(View view, float position)方法。这里的position要注意一下,(ps:有个坑)





position根据上面的介绍position是指当前正中间的页面的位置,当position为0时则是正中间的页面,position为1时则整个页面是在右面,position为-1 则整个页面在左面。理解如下图:(根据颜色看滚动过程中position数值变化)



0——1从第0页滑动到第1页(0—— -1)左滑



1——2从第1页滑动到第0页(0——1)右滑



但是这里position有个坑,就是在viewpager绘制页面的时候,在onlayout方法中。想知道原因请阅读完全文。

Activity

public class MyActivity extends AppCompatActivity {
ViewPager mViewPager;
private int[] mLayoutIds={R.layout.fragment_0,R.layout.fragment_1,R.layout.fragment_2};
public static int PAGE_NUM=3;
private MyAdapter mAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mViewPager= (ViewPager) findViewById(R.id.vp);
mAdapter=new MyAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mAdapter);
mViewPager.setOffscreenPageLimit(3);
/*设置tranformer*/
MyPagerTransformer transformer=new MyPagerTransformer();
mViewPager.addOnPageChangeListener(transformer);
mViewPager.setPageTransformer(true,transformer);
}
public class MyAdapter extends FragmentPagerAdapter {

private List<Fragment> mFragments;
public MyAdapter(FragmentManager fm) {
super(fm);
mFragments=new ArrayList<>();
}

@Override
public Fragment getItem(int position) {
Fragment fragment=null;
if (position<=mFragments.size()-1){
fragment=mFragments.get(position);
}else {
fragment= new MyFragment();
//为了传递布局
Bundle bundle=new Bundle();
bundle.putInt("layoutid",mLayoutIds[position]);
//为了填坑,最后解释
bundle.putInt("pageIndex",position);
fragment.setArguments(bundle);
mFragments.add(fragment);
}
return fragment;
}

@Override
public int getCount() {
return PAGE_NUM;
}
}
}


Fragment

public class MyFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Bundle bundle=getArguments();
int layoutid=bundle.getInt("layoutid");
int pageindex=bundle.getInt("pageIndex");
View view= inflater.inflate(layoutid,container,false);
view.setTag(pageindex);
return view;

}
}


PageTransformer

public class MyPagerTransformer implements ViewPager.PageTransformer, ViewPager.OnPageChangeListener {
private int pageIndex;

/**
* 此方法滑动过程中每个view都会回调 @param view     当前view @param position 滑动时数值范围(-1,1)当前滑动位置
*/
@Override
public void transformPage(View view, float position) { /*获取到ViewPager*/
View v = (View) view.getParent();
int color0 = v.getResources().getColor(R.color.accent_A400);
int color1 = v.getResources().getColor(R.color.colorPrimary);
int color2 = v.getResources().getColor(R.color.accent_A400);
int tag = (int) view.getTag();
int color = color0;
//ArgbEvaluator 用于颜色渐变
ArgbEvaluator argbEvaluator = new ArgbEvaluator();
//为了填坑所以传了一个参数tag
if (tag == pageIndex) {
switch (pageIndex) {
case 0:
color = (int) argbEvaluator.evaluate(Math.abs(position), color0, color1);
break;
case 1:
color = (int) argbEvaluator.evaluate(Math.abs(position), color1, color2);
break;
case 2:
color = (int) argbEvaluator.evaluate(Math.abs(position), color2, color1);
break;
default:
break;
}
v.setBackgroundColor(color);
}
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
pageIndex = position;
Log.e("位置pageIndex", "" + pageIndex);

}

@Override
public void onPageScrollStateChanged(int state) {

}
}


解释

主要就是针对这段代码看的ViewPager中的源码。



看下添加tag判断的效果图:



不添加tag判断的效果图:



为什么添加了tag的就能正常显示不添加的连首页的颜色都不对呢?原因就在于position,在viewpager创建布局时,会涉及transformPage方法的调用,此时position的数值并不是从-1~1而是从0~pagesize-1;为什么是0~pagesize-1,具体要看viewpager的源码。一步步看。

1、在onLayout()方法中调用了scrollToItem方法





2、在ScrollToItem方法中调用了pagescrolled



3、在pageScrolled中调用了onPageScrolled



4、最后,只看onPageScrolled方法





方法中红线框出来的部分是重点。此时scrollx=0,由于child.getleft数值不同,比如item0.getleft=0,item1.getleft=getClientWidth(),item2.getleft=2*getClientWidth()。item3.getleft=3*getClientWidth()以此类推。所以在第一次布局时position的数值范围并不是-1~1而是0~pagesize-1。之后滑动时scrollX数值变化,不再为0,所以之后position范围为-1~1了,但是不要忘记每次停止滑动时又会重新调onlayout方法,所以position的数值又会变化,为此设置tag进行区别。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐