Android中用RxJava和ViewPager實(shí)現(xiàn)輪播圖
前言
很多人要實(shí)現(xiàn)輪播圖都會(huì)想到使用ViewPager + Handler來(lái)完成輪播圖的效果。但是在RxJava快速發(fā)展的情況下,已經(jīng)可以使用RxJava來(lái)代替Handler完成這樣任務(wù)了。
下面我們就來(lái)介紹如何實(shí)現(xiàn)RxJava+ViewPager的輪播圖。
效果圖如下

ViewPager的操作
說(shuō)到ViwePager應(yīng)該大家都不陌生,它可以結(jié)合普通的View也可以結(jié)合Fragment一起使用。在此我也就不對(duì)它的使用方法進(jìn)行過(guò)多的介紹了。直接開始介紹輪播的方法。
常見的輪播操作
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)前的頁(yè)號(hào),避免播放的時(shí)候頁(yè)面顯示不正確。
currentItem = msg.arg1;
break;
default:
break;
}
}
...
}
以上就是比較常見的輪播圖的代碼,我只是在網(wǎng)上隨便找的。首先它的代碼中將PagerAdapter的getCount()返回了一個(gè)Integer.MAX_VALUE;它的目的是為了讓圖片一直的播放下去,但是在一些極限情況下還是會(huì)crash的,并且它返回的數(shù)量太大了在一定程度上對(duì)內(nèi)存也造成了較大的消耗。其次我們可以看到handler的代碼極其的冗雜,不僅多而且邏輯也比較麻煩。 現(xiàn)在我們針對(duì)剛才的問題來(lái)進(jìn)行優(yōu)化
更好的輪播操作
更好的無(wú)限播放:設(shè)置頁(yè)卡視圖列表時(shí),在前后額外各加一個(gè)頁(yè)卡。最前面加最后一張圖片,最后面加第1張圖片。然后每當(dāng)切換到最前的頁(yè)卡時(shí),就替換成倒數(shù)第2個(gè)頁(yè)卡;每當(dāng)切換到最后的頁(yè)卡時(shí),就替換成第2個(gè)頁(yè)卡。這樣一來(lái)就形成了連貫,自然實(shí)現(xiàn)了無(wú)限滑動(dòng)的功能。
1)設(shè)置ViewPager的視圖列表時(shí),在前后各加一個(gè)頁(yè)卡。
for (int i = 0; i < count + 2; i++) {
if (i == 0) {// 將最前面一頁(yè)設(shè)置成本來(lái)最后的那頁(yè)
Glide.with(context).
load(imageTitleBeanList.get(count - 1).getImageUrl()).into(ivImage);
tvTitle.setText(imageTitleBeanList.get(count - 1).getTitle());
} else if (i == count + 1) {// 將最后面一頁(yè)設(shè)置成本來(lái)最前的那頁(yè)
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的頁(yè)卡狀態(tài)改變中,當(dāng)滑動(dòng)到第1個(gè)頁(yè)卡時(shí)替換成倒數(shù)第2個(gè)頁(yè)卡;當(dāng)滑動(dòng)到最后一個(gè)頁(yè)卡時(shí)替換成第2個(gè)頁(yè)卡。
@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來(lái)替代了。
Interval 操作符
創(chuàng)建一個(gè)按固定時(shí)間間隔發(fā)射整數(shù)序列的Observable

Interval操作符返回一個(gè)Observable,它按固定的時(shí)間間隔發(fā)射一個(gè)無(wú)限遞增的整數(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ù)來(lái)指定調(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)行滑動(dòng)操作的時(shí)候,應(yīng)該停止自動(dòng)輪播
mPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//監(jiān)聽ViewPager的觸摸事件,當(dāng)用戶按下的時(shí)候取消注冊(cè),當(dāng)用戶手抬起的時(shí)候再注冊(cè)
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é)
這篇文章主要是對(duì)ViewPager實(shí)現(xiàn)輪播圖的一種總結(jié)。首先提出更好的輪播圖的方法,其實(shí)講解了RxJava中interval操作符的使用,最后用該操作符替換掉Handler完美實(shí)現(xiàn)輪播圖。以上就是這篇文章的全部?jī)?nèi)容,希望本文的內(nèi)容能對(duì)大家有所幫助,如果有疑問大家可以留言交流。
- android?ViewPager實(shí)現(xiàn)一個(gè)無(wú)限輪播圖
- viewpager實(shí)現(xiàn)自動(dòng)循環(huán)輪播圖
- Android Viewpager實(shí)現(xiàn)無(wú)限循環(huán)輪播圖
- Android使用viewpager實(shí)現(xiàn)自動(dòng)無(wú)限輪播圖
- ViewPager打造輪播圖Banner/引導(dǎo)頁(yè)Guide
- Android 使用ViewPager實(shí)現(xiàn)輪播圖效果
- 淺談Viewpager和輪播圖的沖突解決方法
- Android ViewPager實(shí)現(xiàn)輪播圖效果
- Android實(shí)現(xiàn)基于ViewPager的無(wú)限循環(huán)自動(dòng)播放帶指示器的輪播圖CarouselFigureView控件
- 使用ViewPager2實(shí)現(xiàn)簡(jiǎn)易輪播圖效果
相關(guān)文章
Android編程添加快捷方式(Short)到手機(jī)桌面的方法(含添加,刪除及查詢)
這篇文章主要介紹了Android編程添加快捷方式(Short)到手機(jī)桌面的方法,含有針對(duì)桌面快捷方式的添加,刪除及查詢的操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-01-01
Android使用TabLayout+Fragment實(shí)現(xiàn)頂部選項(xiàng)卡
本文通過(guò)實(shí)例代碼給大家介紹了Android使用TabLayout+Fragment實(shí)現(xiàn)頂部選項(xiàng)卡功能,包括TabLyout的使用,感興趣的朋友參考下本文吧2017-05-05
Android開發(fā)之搜索框SearchView用法示例
這篇文章主要介紹了Android開發(fā)之搜索框SearchView用法,結(jié)合實(shí)例形式分析了Android搜索框SearchView的基本功能、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-03-03
Android MenuItem 自定義長(zhǎng)按事件的實(shí)現(xiàn)
這篇文章主要介紹了Android MenuItem 自定義長(zhǎng)按事件的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Android ScrollView的頂部下拉和底部上拉回彈效果
本篇文章主要介紹了Android ScrollView的頂部下拉和底部上拉回彈效果,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Java4Android開發(fā)教程(二)hello world!
一般的開發(fā)教程都是介紹完安裝配置開發(fā)環(huán)境,緊接著來(lái)一篇hello world,算是國(guó)際慣例吧,我們當(dāng)然也不能免俗,哈哈,各位看官請(qǐng)看好了!2014-10-10

