1. 程式人生 > >詳解ViewPager無限迴圈及縮放動畫PageTransformer的實現

詳解ViewPager無限迴圈及縮放動畫PageTransformer的實現

網上也有很多關於無限迴圈的實現方案,但是基本上都效果不是很好,沒有根本上利用和掌握ViewPager和Adapter的展現原理,也基本沒有複用View。

我這裡給大家講解下最新的無限迴圈的實現方案以及下圖這種縮放和透明度漸變的動畫PageTransformer的方案。

1、首先說無限迴圈,這個就要從PagerAdapter的下手。

 @Override
    public int getCount() {
        return mData.size() * 100;
    }
裡面有個getCount方法,這裡預設設定個集合的大小,但是我們需要無限迴圈,所以這裡我們可以設定足夠大,但是一定要用集合的大小進行倍數相乘,方便後面的處理。

還有個關鍵位置:

int select = position < mData.size() ? position : (position % mData.size());
這裡要判斷處理下,如果position大於集合的大小的話,我們這個position要處理下,就是除以集合的大小取餘即可。
2、接下來給大家一個詳細的PagerAdapter的配置:
package com.tandong.viewpagerdemo;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.tandong.viewpagerdemo.R;

import java.util.ArrayList;
import java.util.List;

public class CardPagerAdapter extends PagerAdapter {

    private List<FrameLayout> mViews;
    private List<String> mData;
    private Context context;

    public CardPagerAdapter(Context context, List<String> list) {
        this.context = context;
        mViews = new ArrayList<FrameLayout>();
        this.mData = list;
        for (int i = 0; i < list.size(); i++) {
            mViews.add(null);
        }
    }

    @Override
    public int getCount() {
        return mData.size() * 100;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = LayoutInflater.from(container.getContext())
                .inflate(R.layout.item_card, container, false);
        container.addView(view);
        FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.ll_container);
        ImageView iv_img = (ImageView) view.findViewById(R.id.iv_img);
        TextView tv_select = (TextView) view.findViewById(R.id.tv_select);
        int select = position < mData.size() ? position : (position % mData.size());
        Log.i("info", "位置:" + select + "  " + position + "  " + (position / mData.size()) + "  " + (position % mData.size()));
        tv_select.setText("" + select);
        mViews.set(select, frameLayout);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
        int select = position < mData.size() ? position : (position % mData.size());
        mViews.set(select, null);
    }

}
3、接下來說漸變的PageTransformer:
package com.tandong.viewpagerdemo;

import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;

public class TransFormer implements ViewPager.PageTransformer {
    public static float MIN_ALPHA = 0.5f;
    public static float MIN_SCALE = 0.8f;

    @Override
    public void transformPage(View page, float position) {
        if (position < -1 || position > 1) {
            page.setAlpha(MIN_ALPHA);
            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
            Log.i("info", "縮放:position < -1 || position > 1");
        } else if (position <= 1) { // [-1,1]
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            if (position < 0) {
                float scaleX = 1 + 0.2f * position;
                Log.i("info", "縮放:position < 0");
                page.setScaleX(scaleX);
                page.setScaleY(scaleX);
            } else {
                float scaleX = 1 - 0.2f * position;
                page.setScaleX(scaleX);
                page.setScaleY(scaleX);
                Log.i("info", "縮放:position <= 1 >=0");
            }
            page.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
        }
    }
}

4、最後給一個完整的呼叫:
package com.tandong.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

import com.tandong.viewpagerdemo.R;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private ViewPager vp;
    private CardPagerAdapter cardPagerAdapter;
    private List<String> lists;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        vp = (ViewPager) this.findViewById(R.id.vp);
        lists = new ArrayList<String>();
        for (int i = 0; i < 5; i++) {
            lists.add("");
        }
        cardPagerAdapter = new CardPagerAdapter(this, lists);
//        vp.setPageMargin(10);
        vp.setOffscreenPageLimit(3);
        vp.setPageTransformer(false, new TransFormer());
        vp.setAdapter(cardPagerAdapter);
        vp.setCurrentItem(cardPagerAdapter.getCount() / 2);
    }
}

這裡要實現這個一個介面有3個View的ViewPager效果,需要注意在ViewPager所在的佈局裡設定:
android:clipChildren="false"
把ViewPager和父佈局分別設定這個屬性,然後把ViewPager分別設定:
android:layout_marginLeft="80dp"
android:layout_marginRight="80dp"
這樣才可以實現一個介面3個View的ViewPager效果。