Android中用RxJava和ViewPager實現(xiàn)輪播圖
前言
很多人要實現(xiàn)輪播圖都會想到使用ViewPager + Handler來完成輪播圖的效果。但是在RxJava快速發(fā)展的情況下,已經可以使用RxJava來代替Handler完成這樣任務了。
下面我們就來介紹如何實現(xiàn)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); //檢查消息隊列并移除未發(fā)送的消息,這主要是避免在復雜環(huán)境下消息出現(xiàn)重復等問題。 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: //只要不發(fā)送消息就暫停了 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的,并且它返回的數(shù)量太大了在一定程度上對內存也造成了較大的消耗。其次我們可以看到handler的代碼極其的冗雜,不僅多而且邏輯也比較麻煩。 現(xiàn)在我們針對剛才的問題來進行優(yōu)化
更好的輪播操作
更好的無限播放:設置頁卡視圖列表時,在前后額外各加一個頁卡。最前面加最后一張圖片,最后面加第1張圖片。然后每當切換到最前的頁卡時,就替換成倒數(shù)第2個頁卡;每當切換到最后的頁卡時,就替換成第2個頁卡。這樣一來就形成了連貫,自然實現(xiàn)了無限滑動的功能。
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)在監(jiān)聽ViewPager的頁卡狀態(tài)改變中,當滑動到第1個頁卡時替換成倒數(shù)第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現(xiàn)在就該由RxJava來替代了。
Interval 操作符
創(chuàng)建一個按固定時間間隔發(fā)射整數(shù)序列的Observable
Interval操作符返回一個Observable,它按固定的時間間隔發(fā)射一個無限遞增的整數(shù)序列。
RxJava將這個操作符實現(xiàn)為interval方法。它接受一個表示時間間隔的參數(shù)和一個表示時間單位的參數(shù)。
Javadoc: interval(long,TimeUnit)
Javadoc: interval(long,TimeUnit,Scheduler)
interval默認在computation調度器上執(zhí)行。你也可以傳遞一個可選的Scheduler參數(shù)來指定調度器。
用RxJava取代Handler
public void start() { mViewPagerSubscribe = Observable.interval(5, 5, TimeUnit.SECONDS) // 5s的延遲,5s的循環(huán)時間 .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) { //監(jiān)聽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實現(xiàn)輪播圖的一種總結。首先提出更好的輪播圖的方法,其實講解了RxJava中interval操作符的使用,最后用該操作符替換掉Handler完美實現(xiàn)輪播圖。以上就是這篇文章的全部內容,希望本文的內容能對大家有所幫助,如果有疑問大家可以留言交流。
- android?ViewPager實現(xiàn)一個無限輪播圖
- viewpager實現(xiàn)自動循環(huán)輪播圖
- Android Viewpager實現(xiàn)無限循環(huán)輪播圖
- Android使用viewpager實現(xiàn)自動無限輪播圖
- ViewPager打造輪播圖Banner/引導頁Guide
- Android 使用ViewPager實現(xiàn)輪播圖效果
- 淺談Viewpager和輪播圖的沖突解決方法
- Android ViewPager實現(xiàn)輪播圖效果
- Android實現(xiàn)基于ViewPager的無限循環(huán)自動播放帶指示器的輪播圖CarouselFigureView控件
- 使用ViewPager2實現(xiàn)簡易輪播圖效果
相關文章
Android編程添加快捷方式(Short)到手機桌面的方法(含添加,刪除及查詢)
這篇文章主要介紹了Android編程添加快捷方式(Short)到手機桌面的方法,含有針對桌面快捷方式的添加,刪除及查詢的操作實現(xiàn)技巧,需要的朋友可以參考下2016-01-01Android使用TabLayout+Fragment實現(xiàn)頂部選項卡
本文通過實例代碼給大家介紹了Android使用TabLayout+Fragment實現(xiàn)頂部選項卡功能,包括TabLyout的使用,感興趣的朋友參考下本文吧2017-05-05Android開發(fā)之搜索框SearchView用法示例
這篇文章主要介紹了Android開發(fā)之搜索框SearchView用法,結合實例形式分析了Android搜索框SearchView的基本功能、用法及相關操作注意事項,需要的朋友可以參考下2019-03-03Android MenuItem 自定義長按事件的實現(xiàn)
這篇文章主要介紹了Android MenuItem 自定義長按事件的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Android ScrollView的頂部下拉和底部上拉回彈效果
本篇文章主要介紹了Android ScrollView的頂部下拉和底部上拉回彈效果,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05Java4Android開發(fā)教程(二)hello world!
一般的開發(fā)教程都是介紹完安裝配置開發(fā)環(huán)境,緊接著來一篇hello world,算是國際慣例吧,我們當然也不能免俗,哈哈,各位看官請看好了!2014-10-10