ViewPager 滑動切換效果·
ViewPager是一個允許頁面左右滑動的佈局管理器,不同的頁面可以有不同資料。我們可以通過實現ViewPager.PageTransformer介面來自定義滑動切換效果。
我們需重寫transformPage方法,這個方法有2個引數。第一個引數是指需要設定滑動效果的頁面,包括即將滑出頁面,即將滑入頁面,已經滑出的頁面,我們可以通過第二個引數判斷第一個引數是指哪個頁面。第二個引數不是頁面的下標,它是一個浮點數,在使用者滑動的過程中,它是動態變化的,通過判斷它的值可得出第一個引數的具體指向。
如果ViewPager沒有設定PageMargin屬性,當前頁面的position為0,前一個為-1,後一個為1。在滑動的過程中,position不斷變化。以左滑為例,當ViewPager向左滑動時,當前頁面的position從0逐漸變為-1,即將滑入的頁面position從1逐漸變為0,滑入的後一個頁面position變為1。當設定了PageMargin屬性時,當前頁面依舊為0,前後頁面得加上或減去一個偏移量。(前減後加)。偏移量為 pageMargin / pageWidth 。我們可以在滑動的過程中通過setAlpha()等方法,改變page的屬性達到動態效果。
下面是一個小例子,如圖。
由圖我們可以看到,當頁面沒有處於當前頁面時,頁面變得透明,高度變少,當頁面滑至當前頁面時,恢復正常。另外我們可以看到螢幕不僅顯示當前頁面,而且顯示前後頁面的部分檢視。我們可以通過設定ViewPager父佈局以及ViewPager本身屬性clipChildren為false實現。這個屬性表示是否裁切子View的顯示範圍,設定為false就可以實現上述效果。
public class MyPageTransformer implements ViewPager.PageTransformer { //透明度和高度最小值 private static final float MIN_SCALE = 0.70f; private static final float MIN_ALPHA = 0; @Override public void transformPage(@NonNull View page, float position) { int width = page.getWidth(); int offset = 20 / width; // 20為PageMargin屬性值 if(position < -1 - offset){ page.setAlpha(MIN_ALPHA); page.setScaleY(MIN_SCALE); }else if(position <= 1 + offset){//在[-1-offset,1+offset]範圍 if(position == 0){ //當前頁面 page.setAlpha(1.0f); page.setScaleY(1.0f); }else{ if(position < 0){ //在[-1-offset,0]範圍 //平滑變化 float f = MIN_ALPHA + (1 - MIN_ALPHA) * (1 + position + offset); page.setAlpha(f); float s = MIN_SCALE +(1 - MIN_SCALE) * (1+position + offset); page.setScaleY(s); }else{ //在[0,1+offset]範圍 //平滑變化 float f = MIN_ALPHA + (1 - MIN_ALPHA) * (1 - position + offset); page.setAlpha(f); float s = MIN_SCALE +(1 - MIN_SCALE) * (1 - position + offset); page.setScaleY(s); } } } } }
我們根據不斷變化的引數position來設定頁面屬性,達到平滑過渡的效果。
佈局檔案:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" android:background="@color/colorPrimary" tools:context=".Main3Activity"> <android.support.v4.view.ViewPager android:id="@+id/view_pager_2" android:layout_width="match_parent" android:layout_height="220dp" android:layout_marginLeft="60dp" android:layout_marginRight="60dp" android:clipChildren="false" /> </RelativeLayout>
設定margin留出空間來顯示其他頁面。
activity程式碼:
public class Main3Activity extends AppCompatActivity {
private ViewPager viewPager;
private List<Integer> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
init();
MyPageTransformer n = new MyPageTransformer();
cardViewAdapter adapter = new cardViewAdapter(this, list);
viewPager.setAdapter(adapter);
viewPager.setPageMargin(20);
viewPager.setOffscreenPageLimit(3);//設定快取頁面數量
viewPager.setPageTransformer(false,n);
}
private void init(){
viewPager = findViewById(R.id.view_pager_2);
list = new ArrayList<>();
for(int i = 0; i < 7; i++){
list.add(R.drawable.a);
}
}
}
viewPager介面卡:
public class cardViewAdapter extends PagerAdapter {
private List<Integer> list;
private LayoutInflater inflater;
private Context mContext;
private ImageView iv;
cardViewAdapter(Context context, List<Integer> list){
this.list = list;
mContext = context;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return list.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view = inflater.inflate(R.layout.cardview, container, false);
iv = view.findViewById(R.id.image_card);
iv.setImageResource(list.get(position));
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
}
其他效果同理,修改MyPageTransformer程式碼即可。