Android ViewPager控制元件
阿新 • • 發佈:2018-11-09
前言
ViewPager可以實現多個介面的左右滑動。
1. ViewPager簡單應用
(1) 佈局檔案
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
(2) 介面卡,需要繼承PagerAdapter類
public static class DemoPageAdapter extends PagerAdapter { private List<View> mViewList = new ArrayList<>(); public DemoPageAdapter(Context context) { for (int index = 0; index < 4; index++) { TextView view = (TextView) View.inflate(context, R.layout.viewpager_text, null); view.setText("第" + index + "頁"); mViewList.add(view); } } // 返回介面數量 @Override public int getCount() { return mViewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } // 新增介面,一般會添加當前頁和左右兩邊的頁面 @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(mViewList.get(position)); return mViewList.get(position); } // 去除頁面 @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mViewList.get(position)); } }
(3) 設定介面卡
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(new DemoPageAdapter(this));
(4) 效果如下
2. OnPageChangeListener監聽器
OnPageChangeListener有三個方法
(1) onPageScrolled方法,顯示滑動時頁面狀態。
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
- 手勢從左往右滑動,position為前一頁面,positionOffset從1到0。
- 手勢從右往左滑動,position為當前頁面,positionOffset從0到1。
(2) onPageSelected方法,position是被選擇頁面
public void onPageSelected(int position)
(3) onPageScrollStateChanged方法,
public void onPageScrollStateChanged(int state)
state有三種狀態
- SCROLL_STATE_IDLE,靜止狀態。
- SCROLL_STATE_DRAGGING,開始拖曳。
- SCROLL_STATE_SETTLING,停止拖曳。
3. 迴圈的ViewPager
如何實現迴圈的ViewPager,我們需要在邊界的時候做一些特殊處理。
(1) 在第一個頁面之前和最後一個頁面之後,分別新增一個介面,這樣才能實現迴圈。
public static class CyclePageAdapter extends PagerAdapter {
private List<View> mViewList = new ArrayList<>();
public CyclePageAdapter(Context context) {
for (int index = 0; index < 4; index++) {
TextView view = (TextView) View.inflate(context, R.layout.viewpager_text, null);
view.setText("第" + index + "頁");
mViewList.add(view);
}
}
// 返回介面數量+2
@Override
public int getCount() {
return mViewList.size() + 2;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view;
if (position == 0) {
// 第一個介面,選擇原來的最後一個介面
view = mViewList.get(mViewList.size() - 1);
} else if (position == mViewList.size() + 1) {
// 最後一個介面,選擇原來的第一個介面
view = mViewList.get(0);
} else {
// 原有的依次從0開始
view = mViewList.get(position - 1);
}
// 頁面如果重複新增,會發生異常
try {
container.addView(view);
} catch (Exception e) {
}
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 不在刪除頁面
}
}
(2) 到達實際邊界以後,切換當前頁。
final ViewPager viewPager = findViewById(R.id.view_pager);
final PagerAdapter adapter = new CyclePageAdapter(this);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
int position = viewPager.getCurrentItem();
if (position == 0) {
// 第一個介面,切換到原來的最後一個介面
viewPager.setCurrentItem(adapter.getCount() - 2, false);
} else if (position == adapter.getCount() - 1) {
// 最後一個介面,切換到原來的第一個介面
viewPager.setCurrentItem(1, false);
}
}
}
});
// 初始頁為1
viewPager.setCurrentItem(1);
(3) 效果如下
4. PageTransformer實現個性的切換動畫
transformPage(View page, float position)
方法實現不一樣的動畫,
- 手勢從右往左滑動,當前頁面position從0->-1,而下一頁面position從1->0。
- 手勢從左往右滑動,當前頁面position為0->1,而前一頁面position從-1->0。
定義一個動畫,前一頁面左右移動,而後一頁面位置不變但伸縮顯示。
private class DemoPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View page, float position) {
if (position < -1) {
page.setAlpha(0);
} else if (position <= 0) {
// 左右移動,並且移除時變透明
page.setAlpha(1 + position);
} else if (position < 1) {
// 去除左右移動效果
page.setTranslationX(-page.getWidth() * position);
// 進入時變大,移除時變小
page.setScaleX(1 - position/2);
page.setScaleY(1 - position/2);
page.setAlpha(1 - position);
} else {
page.setAlpha(0);
}
}
}
效果如下
5. 自定義廣告頁
廣告頁長被用於首頁,可以自己切換,也可以手動切換。
使用ViewPager實現廣告頁,主要是要判斷是否在手動切換,可以新增OnPageChangeListener來判斷。
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private boolean mDragging = false;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE && mDragging) {
mHandler.sendEmptyMessageDelayed(MOVE_TO_NEXT, 3000);
mDragging = false;
} else if (state == ViewPager.SCROLL_STATE_DRAGGING){
mHandler.removeMessages(MOVE_TO_NEXT);
mDragging = true;
}
}
});
mHandler.sendEmptyMessageDelayed(MOVE_TO_NEXT, 3000);
Handler類處理自動切換事件
private static final int MOVE_TO_NEXT = 1;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MOVE_TO_NEXT) {
int item = mViewPager.getCurrentItem();
if (++item >= mAdapter.getCount()) {
item = 0;
}
mViewPager.setCurrentItem(item);
mHandler.sendEmptyMessageDelayed(MOVE_TO_NEXT, 3000);
}
}
};