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

Android——ViewPager实现3D画廊效果(ViewPager的加载动画)

2016-11-03 17:55 1031 查看
这个例子相信很多人已经接触过了,我今天觉得好玩自己写了写,参照了网上大家的一些例子,现在总结下自己的感受吧。

ViewPager的用法

android:clipChildren=”false”属性

ViewPager切换动画

一些注意事项

部分代码

ViewPager的基础用法

viewpager的实现还是比较简单的,viewpager中可以添加view,Activity和Fragment。添加Activity时要通过LocalActivityManager中startActivity(id,intent).getDecorView();方法来得多Activity对应的view;viewpager中添加Fragment时要使用FragmentViewPager。今天的例子我们使用最简单的添加view的方式来实现viewPager,所以我们使用PagerAdapter来为viewpager填充数据。

PagerAdapter中必须实现这四个方法:

(1)public int getCount()

(2)public Object instantiateItem(ViewGroup container, int position)

(3)public void destroyItem(ViewGroup container, int position, Object object)

(4)public boolean isViewFromObject(View view, Object object)

android:clipChildren=”false”属性

android:clipChildren的意思:是否限制子View在其范围内,默认值为true。在这个例子中我们想要实现画廊效果,所以android:clipChildren

设置为false,而且还必须是在ViewPager的父布局设置,否则没有效果的。同时注意要实现图片中的效果,ViewPager的宽度是不能设为match_parent的,ViewPager宽度与卡片的宽度设置一致即可。

viewpager切换动画

我们所看到的3D切换效果其实是通过设置viewPager的切换动画来实现的,我们可以多个不同的动画类来实现不同的切换效果,这里我会给出两个例子。效果如下图:

注意事项

1、上面提到的android:clipChildren很重要,如果不添加这个属性则无法实现画廊的效果,一个页面只能展示ViewPager的一个View。这个属性只要添加在ViewPager的父布局即可。

2、ViewPager每个View之间的间距问题,我这里使用了CardView来实现圆角的效果,一开始没有特别设置CardView的属性只加了圆角值,效果不甚满意,View之间的间距太小,后来添加app:cardUseCompatPadding=”true”属性,间距变大,这个属性的意思就是给CardView设置Padding,有兴趣的同学可以深入研究,这里我只介绍下这个属性,具体参考我CardView的文章。

3、xml布局文件要特别注意,ViewPager的宽度要和Item保持一致,不能是match_parent。

4、Item的上下间距可以通过Item的margin值来设置。

部分代码

1、gallery.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:clipChildren="false"
android:gravity="center"
android:layerType="software">

<android.support.v4.view.ViewPager
android:id="@+id/gallery"
android:layout_width="200dp"
android:layout_height="340dp"/>
</LinearLayout>


这是个实现3D切换效果的动画,效果如下图:



public class MyTransformation implements PageTransformer {

private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
private static final float MAX_ROTATE = 30;
private Camera camera = new Camera();

@Override
public void transformPage(View page, float position) {
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float rotate = 20 * Math.abs(position);
if (position < -1) {

} else if (position < 0) {
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
page.setRotationY(rotate);
} else if (position >= 0 && position < 1) {
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
page.setRotationY(-rotate);
} else if (position >= 1) {
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
page.setRotationY(-rotate);
}
}
}


这是个实现扁平切换,中间放大,两边模糊的动画,效果如下图:



public class ZoomOutPageTransformer implements ViewPager.PageTransformer {

private static final float MIN_SCALE = 0.9f;
private static final float MIN_ALPHA = 0.5f;

private static float defaultScale = 0.9f;

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);
view.setScaleX(defaultScale);
view.setScaleY(defaultScale);
} 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);
view.setScaleX(defaultScale);
view.setScaleY(defaultScale);
}
}
}


这个类实现了图片效果:

public class ImageUtil {
public static Bitmap getReverseBitmapById(int resId, Context context) {
Bitmap sourceBitmap = BitmapFactory.decodeResource(context.getResources(), resId);
Matrix matrix = new Matrix();
matrix.setScale(1, -1);
Bitmap inverseBitmap = Bitmap.createBitmap(sourceBitmap, 0, sourceBitmap.getHeight() / 2,
sourceBitmap.getWidth(), sourceBitmap.getHeight() / 3, matrix, false);
Bitmap groupbBitmap = Bitmap.createBitmap(sourceBitmap.getWidth(), sourceBitmap.getHeight
() + sourceBitmap.getHeight() / 3 + 60, sourceBitmap.getConfig());
Canvas gCanvas = new Canvas(groupbBitmap);
gCanvas.drawBitmap(sourceBitmap, 0, 0, null);
gCanvas.drawBitmap(inverseBitmap, 0, sourceBitmap.getHeight() + 100, null);
Paint paint = new Paint();
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
LinearGradient shader = new LinearGradient(0, sourceBitmap.getHeight() + 50, 0,
groupbBitmap.getHeight(), Color.BLACK, Color.TRANSPARENT, tileMode);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
gCanvas.drawRect(0, sourceBitmap.getHeight() + 50, sourceBitmap.getWidth(), groupbBitmap
.getHeight(), paint);
return groupbBitmap;
}
}


设置viewpager的切换动画
viewpager.setOffscreenPageLimit(5);
viewpager.setPageTransformer(true, new MyTransformation());
//viewpager.setPageTransformer(true, new ZoomOutPageTransformer());


将父布局的touch事件传递给viewpager,解决触摸滑动ViewPager左右两边的页面无反应的问题:
findViewById(R.id.activity_main).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return gallery.dispatchTouchEvent(motionEvent);
}
});


class GalleryAdapter extends PagerAdapter {
private int selectPos = 0;
private List<View> viewList = new ArrayList<View>();
Integer[] images = {R.drawable.img0001, R.drawable.img0030,
R.drawable.img0100, R.drawable.img0130, R.drawable.img0200,
R.drawable.img0230, R.drawable.img0330, R.drawable.img0354};
String[] names = {"电影", "冰封重生之门", "超人", "GOLD WAR", "寒颤", "别有动机", "变脸2", "韩国电影"};

public GalleryAdapter() {

}

@Override
public int getCount() {
return images.length;
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(Gallery.this).inflate(R.layout
.gallery_item, null);
ImageView poster = (ImageView) view.findViewById(R.id.poster);
poster.setImageResource(images[position]);
// view.setImageBitmap(ImageUtil.getReverseBitmapById(images[i],Gallery.this));
TextView name = (TextView) view.findViewById(R.id.name);
name.setText(names[position]);
viewpager.addView(view);
return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
gallery.removeView((View) object);
}
}


今天写的有点匆忙,有空继续更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 动画 3d viewpager
相关文章推荐