Android Viewpager实现3D画廊效果

来源:互联网 发布:中国国家顶级域名证书 编辑:程序博客网 时间:2024/06/02 15:36

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

  • 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的宽度是不能设为match_parent的,ViewPager宽度与卡片的宽度设置一致即可。

viewpager切换动画

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

部分代码

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);        }    }

今天写的有点匆忙,有空继续更新。

0 0