Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中用RxJava和ViewPager實現輪播圖

Android中用RxJava和ViewPager實現輪播圖

編輯:關於Android編程

前言

很多人要實現輪播圖都會想到使用ViewPager + Handler來完成輪播圖的效果。但是在RxJava快速發展的情況下,已經可以使用RxJava來代替Handler完成這樣任務了。

下面我們就來介紹如何實現RxJava+ViewPager的輪播圖。

效果圖如下

ViewPager的操作

說到ViwePager應該大家都不陌生,它可以結合普通的View也可以結合Fragment一起使用。在此我也就不對它的使用方法進行過多的介紹了。直接開始介紹輪播的方法。

常見的輪播操作

private class ImageAdapter extends PagerAdapter{

 private ArrayList<ImageView> viewlist;

 public ImageAdapter(ArrayList<ImageView> viewlist) {
  this.viewlist = viewlist;
 }

 @Override
 public int getCount() {
  //設置成最大,使用戶看不到邊界
  return Integer.MAX_VALUE;
 }
 ....
}
private static class ImageHandler extends Handler{
 ...
 @Override
 public void handleMessage(Message msg) {
  super.handleMessage(msg);
  //檢查消息隊列並移除未發送的消息,這主要是避免在復雜環境下消息出現重復等問題。
  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);
    //准備下次播放
    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;
  }
 }
 ...
}

以上就是比較常見的輪播圖的代碼,我只是在網上隨便找的。首先它的代碼中將PagerAdapter的getCount()返回了一個Integer.MAX_VALUE;它的目的是為了讓圖片一直的播放下去,但是在一些極限情況下還是會crash的,並且它返回的數量太大了在一定程度上對內存也造成了較大的消耗。其次我們可以看到handler的代碼極其的冗雜,不僅多而且邏輯也比較麻煩。 現在我們針對剛才的問題來進行優化

更好的輪播操作

更好的無限播放:設置頁卡視圖列表時,在前後額外各加一個頁卡。最前面加最後一張圖片,最後面加第1張圖片。然後每當切換到最前的頁卡時,就替換成倒數第2個頁卡;每當切換到最後的頁卡時,就替換成第2個頁卡。這樣一來就形成了連貫,自然實現了無限滑動的功能。

1)設置ViewPager的視圖列表時,在前後各加一個頁卡。

for (int i = 0; i < count + 2; i++) {
 if (i == 0) {// 將最前面一頁設置成本來最後的那頁
  Glide.with(context).
    load(imageTitleBeanList.get(count - 1).getImageUrl()).into(ivImage);
  tvTitle.setText(imageTitleBeanList.get(count - 1).getTitle());
 } else if (i == count + 1) {// 將最後面一頁設置成本來最前的那頁
  Glide.with(context).
    load(imageTitleBeanList.get(0).getImageUrl()).into(ivImage);
  tvTitle.setText(imageTitleBeanList.get(0).getTitle());
 } else {
  Glide.with(context).
    load(imageTitleBeanList.get(i - 1).getImageUrl()).into(ivImage);
  tvTitle.setText(imageTitleBeanList.get(i - 1).getTitle());
 }
 // 將設置好的View添加到View列表中
 viewList.add(view);
}

2)在監聽ViewPager的頁卡狀態改變中,當滑動到第1個頁卡時替換成倒數第2個頁卡;當滑動到最後一個頁卡時替換成第2個頁卡。

@Override
public void onPageScrollStateChanged(int state) {
 switch (state) {
  // 閒置中
  case ViewPager.SCROLL_STATE_IDLE:
   // “偷梁換柱”
   if (vpImageTitle.getCurrentItem() == 0) {
    vpImageTitle.setCurrentItem(count, false);
   } else if (vpImageTitle.getCurrentItem() == count + 1) {
    vpImageTitle.setCurrentItem(1, false);
   }
   currentItem = vpImageTitle.getCurrentItem();
   break;
 }
}

Handler現在就該由RxJava來替代了。

Interval 操作符

創建一個按固定時間間隔發射整數序列的Observable


Interval操作符返回一個Observable,它按固定的時間間隔發射一個無限遞增的整數序列。


RxJava將這個操作符實現為interval方法。它接受一個表示時間間隔的參數和一個表示時間單位的參數。

Javadoc: interval(long,TimeUnit)

Javadoc: interval(long,TimeUnit,Scheduler)

interval默認在computation調度器上執行。你也可以傳遞一個可選的Scheduler參數來指定調度器。

用RxJava取代Handler

public void start() {
 mViewPagerSubscribe = Observable.interval(5, 5, TimeUnit.SECONDS) // 5s的延遲,5s的循環時間
  .subscribeOn(AndroidSchedulers.mainThread())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Action1<Long>() {
   @Override
   public void call(Long aLong) {
    // 進行輪播操作
    if (mWeeklyMovieInfos != null && mWeeklyMovieInfos.size() > 0 && isAutoPlay) {
     mCurrentPage++;
     mWeeklyViewPager.setCurrentItem(mCurrentPage);
    }
   }
  });
}

為了更好的用戶體驗,在用戶進行滑動操作的時候,應該停止自動輪播

mPager.setOnTouchListener(new View.OnTouchListener() {
 @Override
 public boolean onTouch(View v, MotionEvent event) {
 //監聽ViewPager的觸摸事件,當用戶按下的時候取消注冊,當用戶手抬起的時候再注冊
  switch (event.getAction()){
   case MotionEvent.ACTION_DOWN:
    stop();
    break;
   case MotionEvent.ACTION_UP:
    start();
    break; 
  }
  return false;
 }});

public void stop() {
 if(mViewPagerSubscribe.isUnsubscribed()) { 
  mViewPagerSubscribe.unsubscribe();
 }
}

總結

這篇文章主要是對ViewPager實現輪播圖的一種總結。首先提出更好的輪播圖的方法,其實講解了RxJava中interval操作符的使用,最後用該操作符替換掉Handler完美實現輪播圖。以上就是這篇文章的全部內容,希望本文的內容能對大家有所幫助,如果有疑問大家可以留言交流。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved