Android切換動畫之ViewPager

  有過開發經驗的程序員都知道這個效果,就是當咱們第一次安裝一個軟件時有一個使用說明的圖片切換效果,他是如何實現的呢?今天咱們就一塊兒學習一下吧,難度係數1.0,就是隻要你仔細分析,均可以學會。廢話很少說,下面咱們開始本篇的介紹。html

  本篇我須要使用到ViewPager,對於ViewPager的介紹,就再也不詳述,網上關於ViewPager的介紹不少,你們能夠自行去了解。java

  再進行動畫效果製做以前咱們先實現一個圖片的切換效果。android

  佈局文件:程序員

<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:ide

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的切換動畫就已經爲你們介紹完畢,內容較多,你們有什麼疑問能夠留言交流。

相關文章
相關標籤/搜索