Android客戶端實(shí)現(xiàn)圖片輪播控件
本文和大家一起寫(xiě)一個(gè)Android圖片輪播控件,供大家參考,具體內(nèi)容如下
1. 輪播控件的組成部分
我們以知乎日?qǐng)?bào)Android客戶端的輪播控件為例,分析一下輪播控件的主要組成:
首先我們要有用來(lái)顯示圖片的View對(duì)象,根據(jù)上圖中底部中央的5個(gè)點(diǎn),我們知道需要5個(gè)ImageView來(lái)顯示需要輪播的圖片,另外還需要5個(gè)ImageView來(lái)顯示5個(gè)點(diǎn)?,F(xiàn)在考慮以下輪播組件應(yīng)該具有的行為,首先需要每隔一定時(shí)間間隔切換到下一張圖片,并且圖片間切換的效果應(yīng)該是平滑的,就像“翻書(shū)”一樣。由此我們可以想到將5個(gè)圖片當(dāng)做ViewPager的Page,這樣圖片切換時(shí)自然會(huì)有平滑的效果。接下來(lái),我們還要給底部的5個(gè)小點(diǎn)找一個(gè)父容器,由于它們是線性排列的,所以用LinearLayout是再合適不過(guò)了。然后,我們還要把ViewPager和容納5個(gè)點(diǎn)的LinearLayout放入一個(gè)父容器中,這里我們選擇使用垂直排列子View的LinearLayout。
這樣一來(lái),我們就得到了輪播控件的布局文件(carousel_layout.xml):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/dots" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:gravity="center" android:orientation="horizontal" android:padding="8dp" > </LinearLayout> </LinearLayout>
通過(guò)對(duì)輪播控件的組成部分進(jìn)行分析,我們已經(jīng)確定了用什么“數(shù)據(jù)結(jié)構(gòu)”來(lái)表示一個(gè)輪播組件,那么接下來(lái),我們要做的就是實(shí)現(xiàn)輪播組件的”算法“,也就是業(yè)務(wù)邏輯。
2. 輪播組件的行為分析
輪播控件首先要具有的行為是自動(dòng)播放,也就是每隔一定事件間隔(通常是3到5秒),便自動(dòng)”翻到下一頁(yè)“。為了實(shí)現(xiàn)這一點(diǎn),我們可以維護(hù)一個(gè)currentItem變量來(lái)記錄當(dāng)前正在顯示的圖片,然后設(shè)置一個(gè)定時(shí)任務(wù),調(diào)用ViewPager的setCurrentItem方法設(shè)置當(dāng)前要顯示的圖片,并將currentItem設(shè)為下一張要顯示的圖片。有一點(diǎn)需要我們注意的便是播放到最后一張圖片時(shí),下一個(gè)被顯示的應(yīng)該是第一個(gè)圖片,而且切換的效果也不再是平滑的。
輪播控件的還要能響應(yīng)我們的滑動(dòng)動(dòng)作,也就是我們能夠通過(guò)左右滑動(dòng)來(lái)在不同的圖片之間切換,這個(gè)行為ViewPager自動(dòng)為我們提供了。另外還有一個(gè)輪播控件應(yīng)該具備的行為是:當(dāng)切換到指定圖片時(shí),相應(yīng)的圓點(diǎn)應(yīng)該以區(qū)別其他4個(gè)圓點(diǎn)的顏色顯示,以便用戶能夠知道當(dāng)前正在播放的是第幾個(gè)圖片。要實(shí)現(xiàn)這一點(diǎn)也不復(fù)雜,只需要為ViewPager添加一個(gè)OnPageChangeListener監(jiān)聽(tīng)器,然后重寫(xiě)相應(yīng)的回調(diào)方法即可,這樣當(dāng)用戶選定了某個(gè)Page時(shí),onPageSelected方法會(huì)被回調(diào),系統(tǒng)會(huì)傳入當(dāng)前Page的索引,我們便可以根據(jù)這個(gè)索引設(shè)置相應(yīng)的圓點(diǎn)顏色。
3. 輪播控件的具體實(shí)現(xiàn)
經(jīng)過(guò)以上的分析,我們已經(jīng)清楚的了解了輪播組件的表示及業(yè)務(wù)邏輯,接下來(lái)只要我們用Java把這些描述出來(lái)就大功告成了。
(1)定時(shí)任務(wù)
我們需要定時(shí)執(zhí)行“改變ViewPager當(dāng)前Page為下一個(gè)Page”這一任務(wù),這里我們采用Handler來(lái)實(shí)現(xiàn),代碼如下:
mHandler.postDelayed(task, DELAY); private final Runnable task = new Runnable() { @Override public void run() { if (isAutoPlay) { currentItem = (currentItem + 1) % (mTopStories.size()); mVP.setCurrentItem(currentItem); mHandler.postDelayed(task, DELAY); } else { mHandler.postDelayed(task, DELAY); } } };
在以上代碼中,DELAY代表我們?cè)O(shè)置的一個(gè)延遲常量(單位ms)。由于我們需要的是循環(huán)播放,因此第5張顯示完畢后應(yīng)該顯示第一張,所以我們要想第6行那樣進(jìn)行一個(gè)模運(yùn)算,這樣currentItem就在0到4之間不停變化了。注意第5行有一個(gè)isAutoPlay變量,這個(gè)變量表示當(dāng)前是否應(yīng)該自動(dòng)播放。那么什么時(shí)候不應(yīng)該自動(dòng)播放呢?我們知道當(dāng)我們滑動(dòng)手指切換圖片時(shí),圖片會(huì)“跟隨”著我們的手,就好比我們翻書(shū)頁(yè)的時(shí)候,只有松開(kāi)了手書(shū)頁(yè)才能落下。所以我們正在“拖動(dòng)”圖片時(shí),也就是我們的手還沒(méi)松開(kāi)時(shí),輪播控件是不應(yīng)該自動(dòng)播放的。為了實(shí)現(xiàn)這一點(diǎn),我們只需重寫(xiě)OnPageChangeListener中的onPageScrollStateChanged方法,在當(dāng)前狀態(tài)為“拖動(dòng)”時(shí)設(shè)置isAutoPlay變量為false。從第10行我們可以知道,當(dāng)autoPlay為false時(shí),不會(huì)改變當(dāng)前顯示的圖片,僅僅會(huì)等過(guò)了DELAY指定的時(shí)間后再執(zhí)行下一次定時(shí)任務(wù)。
(2)OnPageChangeListener
上面我們提到了要給ViewPager添加一個(gè)OnPageChangeListener監(jiān)聽(tīng)器對(duì)象,來(lái)實(shí)現(xiàn)小圓點(diǎn)顏色的改變以及autoPlay變量的賦值。具體的實(shí)現(xiàn)請(qǐng)看以下代碼,代碼的含義都很直接:
class TopOnPageChangeListener implements ViewPager.OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { for (int i = 0; i < mDotsIV.size(); i++) { if (i == position) { mDotsIV.get(i).setImageResource(R.drawable.dot_focus); } else { mDotsIV.get(i).setImageResource(R.drawable.dot_blur); } } } @Override public void onPageScrollStateChanged(int state) { switch (state) { //SCROLL_STATE_DRAGGING case 1: isAutoPlay = false; break; //SCROLL_STATE_SETTLING case 2: isAutoPlay = true; break; default: break; } } }
在以上代碼的第10到16行,我們重寫(xiě)了onPageSelected方法,position參數(shù)表示當(dāng)前Page的索引。這個(gè)方法中,我們?cè)O(shè)置當(dāng)前圖片對(duì)應(yīng)的圓點(diǎn)圖片為dot_focus,設(shè)置其他圓點(diǎn)的圖片為dot_blur,這樣用戶就能知道當(dāng)前的位置。在第21行到32行,我們重寫(xiě)了onPageScrollStateChanged方法,state參數(shù)代表了當(dāng)前的“滾動(dòng)狀態(tài),這個(gè)值為1表示當(dāng)前用戶正在”拖動(dòng)“的過(guò)程中,因此要設(shè)置isAutoPlay為false;這個(gè)值為2表示用戶松開(kāi)了手,圖片正在”滾動(dòng)“中,這時(shí)我們就要把isAutoPlay設(shè)回默認(rèn)值true,恢復(fù)自動(dòng)播放。
(3) 更進(jìn)一步
有時(shí)候我們希望能夠從最后一頁(yè)直接“翻到”第一頁(yè),而這種行為默認(rèn)不被PagerView所支持,要想實(shí)現(xiàn)這個(gè)行為,我們可以在PagerView中增加一些“輔助頁(yè)”,并重寫(xiě)OnPageChangeLisener中的相關(guān)方法。然而我們?cè)诤芏鄨?chǎng)景中只需要保持PagerView的默認(rèn)行為就好,要注意增加任何功能都要考慮應(yīng)用場(chǎng)景,避免畫(huà)蛇添足。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
- Android實(shí)現(xiàn)圖片輪播效果的兩種方法
- Android實(shí)現(xiàn)圖片輪播效果
- Android自動(dòng)播放Banner圖片輪播效果
- Android實(shí)現(xiàn)廣告圖片輪播效果
- Android ViewPager實(shí)現(xiàn)圖片輪播效果
- Android實(shí)現(xiàn)圖片輪播切換實(shí)例代碼
- Android自定義圖片輪播Banner控件使用解析
- Android高級(jí)圖片滾動(dòng)控件實(shí)現(xiàn)3D版圖片輪播器
- Android線程實(shí)現(xiàn)圖片輪播
- Android實(shí)現(xiàn)背景圖片輪播
相關(guān)文章
基于Android開(kāi)發(fā)支持表情的實(shí)現(xiàn)詳解
本篇文章是對(duì)在Android開(kāi)發(fā)中支持表情的實(shí)現(xiàn)代碼進(jìn)行了介紹。需要的朋友參考下2013-05-05Android檢測(cè)Cursor泄漏的原理以及使用方法
本文介紹如何在 Android 檢測(cè) Cursor 泄漏的原理以及使用方法,還指出幾種常見(jiàn)的出錯(cuò)示例,同時(shí)該方法同樣適合于其他需要檢測(cè)資源泄露的情況,感興趣的朋友可以了解下2013-01-01android RecyclerView的一些優(yōu)化點(diǎn)介紹
大家好,本篇文章主要講的是android RecyclerView的一些優(yōu)化點(diǎn)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12Kotlin 實(shí)現(xiàn)按鈕點(diǎn)擊跳轉(zhuǎn)監(jiān)聽(tīng)事件方式
這篇文章主要介紹了Kotlin 實(shí)現(xiàn)按鈕點(diǎn)擊跳轉(zhuǎn)監(jiān)聽(tīng)事件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03Android?自定義來(lái)電秀實(shí)現(xiàn)總結(jié)
這篇文章主要為大家介紹了Android?自定義來(lái)電秀實(shí)現(xiàn)總結(jié)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Android使用MediaRecorder實(shí)現(xiàn)錄像功能
這篇文章主要為大家詳細(xì)介紹了Android使用MediaRecorder實(shí)現(xiàn)錄像功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Android 按后退鍵退出Android程序的實(shí)現(xiàn)方法
本篇文章介紹了,在Android中按后退鍵退出Android程序的實(shí)現(xiàn)方法。需要的朋友參考下2013-04-04Android Studio中統(tǒng)一管理版本號(hào)引用配置問(wèn)題
這篇文章主要介紹了Android Studio中統(tǒng)一管理版本號(hào)引用配置問(wèn)題,需要的朋友可以參考下2018-01-01Android?實(shí)現(xiàn)APP可切換多語(yǔ)言步驟詳解
如果是單獨(dú)給app加上國(guó)際化,其實(shí)很容易,創(chuàng)建對(duì)應(yīng)的國(guó)家資源文件夾即可,如values-en,values-pt,這篇文章主要介紹了Android?實(shí)現(xiàn)APP可切換多語(yǔ)言,需要的朋友可以參考下2023-11-11