google为viewpager开放了一个接口PageTransformer,用于实现viewpager动画。开发者可以实现这个接口,定义自己想要的动画,同时google定义了两个默认的动画实现 官方实现。
实现一个普通的viewpager。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.luo.androidui.viewpagertest.ViewpagerActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
RelativeLayout>
public class MyPagerAdapter extends PagerAdapter {
private List list;
public MyPagerAdapter(List list) {
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView((View) list.get(position));
return list.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
public class ViewpagerActivity extends AppCompatActivity {
ViewPager viewPager;
int imgid[]={R.drawable.image1,R.drawable.image2,R.drawable.thumb1,R.drawable.thumb2};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);
viewPager = (ViewPager) findViewById(R.id.viewpager);
ArrayList list = new ArrayList();
for (int i=0;inew ImageView(getApplicationContext());
imageView.setImageResource(imgid[i]);
list.add(imageView);
}
MyPagerAdapter myPagerAdapter = new MyPagerAdapter(list);
viewPager.setAdapter(myPagerAdapter);
}
}
上面的3端代码构成了简单的viewpager滑动,如下图效果
从效果图上可以看到这是viewpager正常滑动效果。现在我们使用google定义的滑动效果。
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +
(scaleFactor - MIN_SCALE) /
(1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
如何运用在viewpager中呢?使用viewpager内的一个set注入函数把这个实现传入到viewpager中,
viewPager.setPageTransformer(true,new ZoomOutPageTransformer());
运行观察效果:
从效果中可以看出,滑动时viewpager中的item进行了两个效果,缩小和透明度发生了变化。
在代码中存在判断条件
1. position<-1
2. 1<=position<=1
3. position>1
上面的条件表达有点复杂,我们把它简化一下,简化后如下:
1. (无穷小,-1)
2. [-1,1] 等价于[-1,0],[0,1]
3. (1,无穷大)
viewpager滑动时存在3个item,分别是当前屏幕可见item,可见item的左边和可见item的右边。如图:
主要看2个条件,[-1,0]表示向右滑动,“左边”在手机上显示,“手机屏幕显示的item项”影藏掉,[1,0]表示向左滑动,“右边”在手机上显示,手机屏幕显示的item项”影藏掉。
//从ZoomOutPageTransformer中节选的代码片段
Log.d("view",view.hashCode()+"");
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
在手指滑动的时候打log日志可看到,代码中使用的view是不同的,在瞬间使用了不同的view,说名了手指滑动时,“左边”,“当前”,“右边”三个item都进行了动画处理。日志如图:
假设现在手指向左边滑动,上面的代码条件
if(position<0){
操作当前item(处理:从在手机屏幕上可见,到离开手机屏幕)
}else if(position<1){
操作右边item(处理:从右边不可见,到右边移动到可见)
}