編輯:關於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完美實現輪播圖。以上就是這篇文章的全部內容,希望本文的內容能對大家有所幫助,如果有疑問大家可以留言交流。
我們使用控件AutoCompleteTextView 自動提示時,有時需要設置BaseAdapter,設置BaseAdapter時,需要實現Filterable,手動進行
現在市面上的很多的應用,都帶有下拉列表的功能,將所有選項都放在下拉列表中,當用戶點擊選擇的時候,彈出所有的選項,用戶選擇一項後,下拉列表自動隱藏,很多下拉列表都是用Lis
最近下了個攜程App,點開首頁看,注意到其按鈕在點擊的時候並不是我們經常看到的變色效果,而是先收縮,放開時,再回到原來的大小,感覺這個效果雖然小,但是感覺非常新穎,於是決
本篇博客要分享的一個效果是實現廣告Banner輪播效果,這個效果也比較常見,一些視頻類應用就經常有,就拿360影視大全來舉例吧: 用紅框框住的那個效果就是小巫今