zoukankan      html  css  js  c++  java
  • Android切换动画之ViewPager

      有过开发经验的程序员都知道这个效果,就是当我们第一次安装一个软件时有一个使用说明的图片切换效果,他是如何实现的呢?今天我们就一起学习一下吧,难度系数1.0,就是只要你仔细分析,都可以学会。废话不多说,下面我们开始本篇的介绍。

      本篇我需要使用到ViewPager,对于ViewPager的介绍,就不再详述,网上关于ViewPager的介绍很多,大家可以自行去了解。

      再进行动画效果制作之前我们先实现一个图片的切换效果。

      布局文件:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
        
        <com.example.android_viewpager.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </com.example.android_viewpager.ViewPager>
    
    </RelativeLayout>

      我们的Activity:

    public class MainActivity extends Activity {
        
        private ViewPager mViewPager;//系统提供的
        
        int [] imageIds = {R.drawable.guide_image1, R.drawable.guide_image2, R.drawable.guide_image3};
        List<ImageView> listImager = new ArrayList<ImageView>();
         
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mViewPager = (ViewPager) findViewById(R.id.viewPager);//调用系统提供的
            
            mViewPager.setAdapter(new PagerAdapter() {
                
                @Override
                public void destroyItem(ViewGroup container, int position,
                        Object object) {
                    container.removeView(listImager.get(position));
                }
    
                @Override
                public Object instantiateItem(ViewGroup container, int position) {
                    
                    ImageView imagerView = new ImageView(MainActivity.this);
                    imagerView.setImageResource(imageIds[position]);
                    imagerView.setScaleType(ScaleType.CENTER_CROP);//设置样式
                    container.addView(imagerView);
                    listImager.add(imagerView);
                    return imagerView;
                }
    
                @Override
                public boolean isViewFromObject(View arg0, Object arg1) {
                    return arg0 == arg1;
                }
                
                @Override
                public int getCount() {
                    return imageIds.length;
                }
            });
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
        
    }

      这样我们最简单的使用说明的效果已经做好了。下面我们来一起看一下如何为我们的切换效果添加一些炫酷效果呢?

      首先我们想到的是谷歌有没有为我们封装这样的方法,答案是肯定的,大家可以访问谷歌Android API详细了解其中的机制(http://developer.android.com/training/animation/screen-slide.html )。接下来就有我带领大家先使用一下为ViewPager添加动画效果的实现。

      调用的方法:

    mViewPager.setPageTransformer(true, new DepthPageTransformer());

      DepthPageTransformer.java:

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public class DepthPageTransformer implements ViewPager.PageTransformer {
        
        private static final float MIN_SCALE = 0.75f;
    
        @SuppressLint("NewApi")
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();
    
            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                view.setAlpha(0);
    
            } else if (position <= 0) { // [-1,0]
                // Use the default slide transition when moving to the left page
                view.setAlpha(1);
                view.setTranslationX(0);
                view.setScaleX(1);
                view.setScaleY(1);
    
            } else if (position <= 1) { // (0,1]
                // Fade the page out.
                view.setAlpha(1 - position);
    
                // Counteract the default slide transition
                view.setTranslationX(pageWidth * -position);
    
                // Scale the page down (between MIN_SCALE and 1)
                float scaleFactor = MIN_SCALE
                        + (1 - MIN_SCALE) * (1 - Math.abs(position));
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);
    
            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }
        }
    }

      对于这段代码代码大家直接把官网的拿过来就可以了。好了到这里我们的切换效果已经实现了,大家可以测试一下了。

      是不是一些同学已经发现一个问题了,自己的为什么一点效果都没有,是的,这不是你写错的原因,这是因为我们的动画效果都是通过属性动画实现的,而属性动画又是Android3.0以后的版本才支持的,所以大家不为之困扰,换一个高版本的就可以完美呈现了,当然如果你感觉这个效果还不算理想,官网还为我们提供了一个效果,大家同样的操作就可以了。

      对于上面的提到的关于3.0以前版本不支持的问题,这里我为大家提供一个改进方法:

      我们对DepthPageTransformer.java进行优化:

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public class myDepthPageTransformer implements ViewPager.PageTransformer {
        private static final float MIN_SCALE = 0.75f;
    
        /*
         * 使用ViewHelper替代系统提供的view
         * (non-Javadoc)
         * @see android.support.v4.view.ViewPager.PageTransformer
         * #transformPage(android.view.View, float)
         */
        
        @SuppressLint("NewApi")
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();
    
            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
    //            view.setAlpha(0);
                ViewHelper.setAlpha(view, 0);
    
            } else if (position <= 0) { // [-1,0]
                // Use the default slide transition when moving to the left page
    //            view.setAlpha(1);
                ViewHelper.setAlpha(view, 1);
    //            view.setTranslationX(0);
                ViewHelper.setTranslationX(view, 0);
    //            view.setScaleX(1);
                ViewHelper.setScaleX(view, 1);
    //            view.setScaleY(1);
                ViewHelper.setScaleY(view, 1);
    
            } else if (position <= 1) { // (0,1]
                // Fade the page out.
    //            view.setAlpha(1 - position);
                ViewHelper.setAlpha(view, 1 - position);
    
                // Counteract the default slide transition
    //            view.setTranslationX(pageWidth * -position);
                ViewHelper.setTranslationX(view, pageWidth * -position);
    
                // Scale the page down (between MIN_SCALE and 1)
                float scaleFactor = MIN_SCALE
                        + (1 - MIN_SCALE) * (1 - Math.abs(position));
    //            view.setScaleX(scaleFactor);
                ViewHelper.setScaleX(view, scaleFactor);
    //            view.setScaleY(scaleFactor);
                ViewHelper.setScaleY(view, scaleFactor);
    
            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
    //            view.setAlpha(0);
                ViewHelper.setAlpha(view, 0);
            }
        }
    }

      这样我们通过ViewHelper来替代我们的属性动画属性,来处理我们3.0以前版主不支持属性动画的问题,当我们运行后发现,3.0以后的版本还是没有效果,这是什么原因呢?我们打开ViewPager的源代码发现里面有一句判断:

    if (Build.VERSION.SDK_INT >= 11) //Android版本判断

      对这个就是罪魁祸首,当我们的版本低于3.0时,我们的动画效果代码根本得不到执行,所以如果想要解决这个问题,我们需要从写这个类。把里面setPageTransformer()里面的版本判断进行一下注释;

    public void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) {
            //if (Build.VERSION.SDK_INT >= 11) //Android版本判断
            {
                final boolean hasTransformer = transformer != null;
                final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
                mPageTransformer = transformer;
                setChildrenDrawingOrderEnabledCompat(hasTransformer);
                if (hasTransformer) {
                    mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD;
                } else {
                    mDrawingOrder = DRAW_ORDER_DEFAULT;
                }
                if (needsPopulate) populate();
            }
        }

      然后我们需要把里面的布局文件进行一下更改:

        <com.example.android_viewpager.ViewPagerCompate
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </com.example.android_viewpager.ViewPagerCompate>

      然后把MainActivity进行一些更改:

    mViewPager = (ViewPagerCompate) findViewById(R.id.viewPager);//修改系统提供的

      这样我们刚刚修改的效果就可以在3.0以后的版本显示出来了,是不是感觉很神奇。最后我在为大家介绍一个效果:

    public class RotateDownPagetransformer implements ViewPager.PageTransformer {
    
        private static final float MAX_ROTATE = 20F;
        private static float ROTATE = 0F;
        
        /*
         * 效果分析:
         * 滑动可以分解为:A>B
         * A的position:0.0 >> -1.0
         * B的position:1.0 >> 0.0
         * (non-Javadoc)
         * @see android.support.v4.view.ViewPager.PageTransformer#
         * transformPage(android.view.View, float)
         */
        
        @Override
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();
    
            if (position < -1) { // [-Infinity,-1)
                ViewHelper.setAlpha(view, 0);//设置透明度
            } else if (position <= 0) { // A页position:0.0 >> 1.0
                //计算旋转角度
                ROTATE = MAX_ROTATE * position;
                //设置旋转中心
                ViewHelper.setPivotX(view, pageWidth/2);
                ViewHelper.setPivotY(view, view.getMeasuredHeight());
                //设置选择角度
                ViewHelper.setRotation(view, ROTATE);
                
            } else if (position <= 1) { // B页position:1.0 >> 0.0
                //计算旋转角度
                ROTATE = MAX_ROTATE * position;
                //设置旋转中心
                ViewHelper.setPivotX(view, pageWidth/2);
                ViewHelper.setPivotY(view, view.getMeasuredHeight());
                //设置选择角度
                ViewHelper.setRotation(view, ROTATE);
    
            } else { // (1,+Infinity]
                ViewHelper.setAlpha(view, 0);
            }
        }
    }

      这是一个类似于扇形的切换效果,好了对于ViewPager的切换动画就已经为大家介绍完毕,内容较多,大家有什么疑问可以留言交流。

  • 相关阅读:
    struts2知识系统整理
    JavaScript onload
    百度云如何为用户分配内存空间
    集合运算
    [hdu3530]单调队列
    [hdu4911]逆序对相关
    [hdu5199]统计数据的水题
    [hdu5200]离线+标记
    [hdu5204]水题
    [hdu5203]计数水题
  • 原文地址:https://www.cnblogs.com/AndroidJotting/p/4451591.html
Copyright © 2011-2022 走看看