国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android中用RxJava和ViewPager實(shí)現(xiàn)輪播圖

2019-12-12 05:13:18
字體:
供稿:網(wǎng)友

前言

很多人要實(shí)現(xiàn)輪播圖都會想到使用ViewPager + Handler來完成輪播圖的效果。但是在RxJava快速發(fā)展的情況下,已經(jīng)可以使用RxJava來代替Handler完成這樣任務(wù)了。

下面我們就來介紹如何實(shí)現(xiàn)RxJava+ViewPager的輪播圖。

效果圖如下

ViewPager的操作

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

常見的輪播操作

private class ImageAdapter extends PagerAdapter{ private ArrayList<ImageView> viewlist; public ImageAdapter(ArrayList<ImageView> viewlist) {  this.viewlist = viewlist; } @Override public int getCount() {  //設(shè)置成最大,使用戶看不到邊界  return Integer.MAX_VALUE; } ....}
private static class ImageHandler extends Handler{ ... @Override public void handleMessage(Message msg) {  super.handleMessage(msg);  //檢查消息隊(duì)列并移除未發(fā)送的消息,這主要是避免在復(fù)雜環(huán)境下消息出現(xiàn)重復(fù)等問題。  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);    //準(zhǔn)備下次播放    activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);    break;   case MSG_KEEP_SILENT:    //只要不發(fā)送消息就暫停了    break;   case MSG_BREAK_SILENT:    activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);    break;   case MSG_PAGE_CHANGED:    //記錄當(dāng)前的頁號,避免播放的時(shí)候頁面顯示不正確。    currentItem = msg.arg1;    break;   default:    break;  } } ...}

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

更好的輪播操作

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

1)設(shè)置ViewPager的視圖列表時(shí),在前后各加一個(gè)頁卡。

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

2)在監(jiān)聽ViewPager的頁卡狀態(tài)改變中,當(dāng)滑動到第1個(gè)頁卡時(shí)替換成倒數(shù)第2個(gè)頁卡;當(dāng)滑動到最后一個(gè)頁卡時(shí)替換成第2個(gè)頁卡。

@Overridepublic 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現(xiàn)在就該由RxJava來替代了。

Interval 操作符

創(chuàng)建一個(gè)按固定時(shí)間間隔發(fā)射整數(shù)序列的Observable


Interval操作符返回一個(gè)Observable,它按固定的時(shí)間間隔發(fā)射一個(gè)無限遞增的整數(shù)序列。


RxJava將這個(gè)操作符實(shí)現(xiàn)為interval方法。它接受一個(gè)表示時(shí)間間隔的參數(shù)和一個(gè)表示時(shí)間單位的參數(shù)。

Javadoc: interval(long,TimeUnit)

Javadoc: interval(long,TimeUnit,Scheduler)

interval默認(rèn)在computation調(diào)度器上執(zhí)行。你也可以傳遞一個(gè)可選的Scheduler參數(shù)來指定調(diào)度器。

用RxJava取代Handler

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

為了更好的用戶體驗(yàn),在用戶進(jìn)行滑動操作的時(shí)候,應(yīng)該停止自動輪播

mPager.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //監(jiān)聽ViewPager的觸摸事件,當(dāng)用戶按下的時(shí)候取消注冊,當(dāng)用戶手抬起的時(shí)候再注冊  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(); }}

總結(jié)

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 开鲁县| 云和县| 河源市| 井陉县| 察雅县| 万载县| 静海县| 清水县| 桦川县| 南丰县| 左权县| 青浦区| 禹州市| 巴塘县| 阿城市| 喜德县| 梨树县| 德江县| 石棉县| 石嘴山市| 怀远县| 探索| 油尖旺区| 梁山县| 福州市| 大埔县| 西昌市| 汉沽区| 寿宁县| 杭州市| 璧山县| 临海市| 民县| 万州区| 荃湾区| 信阳市| 湖北省| 彝良县| 斗六市| 临海市| 平原县|