關於ViewPager的自動輪巡和無限循環效果,參考自源網頁:
http://www.cnblogs.com/kobe8/p/4343478.html
源網頁中代碼無法自動輪番播放,需要手動滑動後才啓用輪巡,修正後正常啓用
public class MainActivity extends Activity {
private ImageHandler handler =
new ImageHandler(new WeakReference<MainActivity>(this));
private ViewPager viewPager;
private ImageView view1;
private ImageView view2;
private ImageView view3;
private List<ImageView> views;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.vp_main);
LayoutInflater inflater = LayoutInflater.from(this);
view1 = (ImageView) inflater.inflate(R.layout.vp1_image, null);
view2 = (ImageView) inflater.inflate(R.layout.vp2_image, null);
view3 = (ImageView) inflater.inflate(R.layout.vp3_image, null);
view1.setImageResource(R.drawable.vp1);
view2.setImageResource(R.drawable.vp2);
view3.setImageResource(R.drawable.vp3);
views = new ArrayList<ImageView>();
views.add(view1);
views.add(view2);
views.add(view3);
viewPager.setAdapter(new ImageAdapter(views));
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
//配合Adapter的currentItem字段進行設置
// 當新的頁面被選中時調用
@Override
public void onPageSelected(int arg0) {
Message msg = Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED , arg0, 0);
handler.sendMessage(msg);
}
// 噹噹前頁面被滑動時調用
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
//覆寫該方法實現輪播效果的暫停和恢復
// 當滑動狀態改變時調用
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
switch (arg0) {
case ViewPager.SCROLL_STATE_DRAGGING:
// 正在拖動頁面時執行此處
handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case ViewPager.SCROLL_STATE_IDLE:
// 未拖動頁面時執行此處
handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
default:
break;
}
}
});
viewPager.setCurrentItem(Integer.MAX_VALUE/2);
//開始輪播效果
//如果執行已經被註釋的代碼,則需要在點擊viewpager之後才能進行輪番播放
//因爲在ImageHandler中,爲避免在複雜環境下消息出現重複問題(實際情況是,如果不判斷則一定會重複),對activity.handler.hasMessages(MSG_UPDATE_IMAGE)進行了判斷
//如果activity.handler.hasMessages(MSG_UPDATE_IMAGE),則
//activity.handler.removeMessages(MSG_UPDATE_IMAGE)執行
//會導致MSG_UPDATE_IMAGE消息被清除而不自動輪巡,因此不能首先發送MSG_UPDATE_IMAGE
//handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
handler.sendEmptyMessage(ImageHandler.MSG_BREAK_SILENT);
}
private static class ImageHandler extends Handler{
/**
* 請求更新顯示的View。
*/
protected static final int MSG_UPDATE_IMAGE = 1;
/**
* 請求暫停輪播。
*/
protected static final int MSG_KEEP_SILENT = 2;
/**
* 請求恢復輪播。
*/
protected static final int MSG_BREAK_SILENT = 3;
/**
* 記錄最新的頁號,當用戶手動滑動時需要記錄新頁號,否則會使輪播的頁面出錯。
* 例如當前如果在第一頁,本來準備播放的是第二頁,而這時候用戶滑動到了末頁,
* 則應該播放的是第一頁,如果繼續按照原來的第二頁播放,則邏輯上有問題。
*/
protected static final int MSG_PAGE_CHANGED = 4;
//輪播間隔時間
protected static final long MSG_DELAY = 3000;
//使用弱引用避免Handler泄露.這裏的泛型參數可以不是Activity,也可以是Fragment等
private WeakReference<MainActivity> weakReference;
private int currentItem = 0;
protected ImageHandler(WeakReference<MainActivity> wk) {
// TODO Auto-generated constructor stub
weakReference = wk;
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
MainActivity activity = weakReference.get();
if (activity==null) {
//Activity已經回收,無需再處理UI了
return;
}
//檢查消息隊列並移除未發送的消息,這主要是避免在複雜環境下消息出現重複等問題。
//不判斷則會同時接受多個MSG_UPDATE_IMAGE,並重復輪番播放
if (activity.handler.hasMessages(MSG_UPDATE_IMAGE)) {
activity.handler.removeMessages(MSG_UPDATE_IMAGE);
}
switch (msg.what) {
case MSG_UPDATE_IMAGE:
currentItem++;
activity.viewPager.setCurrentItem(currentItem);
//準備下次播放
Log.d("TAG", "currentItem="+currentItem+"&&msg="+msg);
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_KEEP_SILENT:
//只要不發送消息就暫停了
break;
case MSG_BREAK_SILENT:
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_PAGE_CHANGED:
//記錄當前的頁號,避免播放的時候頁面顯示不正確
currentItem = msg.arg1;
break;
default:
break;
}
}
}
private class ImageAdapter extends PagerAdapter{
private List<ImageView> viewList;
public ImageAdapter(List<ImageView> viewList) {
this.viewList = viewList;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0==arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// DO NOTHING
//Warning:不要在這裏調用removeView
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//對ViewPager頁號求模取出View列表中要顯示的項
position = position%viewList.size();
//如果位置是負數,則做處理
if (position<0) {
position = viewList.size()+position;
}
ImageView view = viewList.get(position);
//如果View已經在之前添加到了一個父組件,則必須先remove,否則會拋出IllegalStateException
ViewParent vp = view.getParent();
if (vp!=null) {
ViewGroup parent = (ViewGroup) vp;
parent.removeView(view);
}
container.addView(view);
return view;
}
}
}