Android使用自定義屬性實(shí)現(xiàn)圖片自動(dòng)播放滾動(dòng)的功能
大家好,記得上次我?guī)е蠹乙黄饘?shí)現(xiàn)了一個(gè)類似與淘寶客戶端中帶有的圖片滾動(dòng)播放器的效果,但是在做完了之后,發(fā)現(xiàn)忘了加入圖片自動(dòng)播放的功能(或許是我有意忘記加的.....),結(jié)果圖片只能通過(guò)手指滑動(dòng)來(lái)播放。于是今天我將再次帶領(lǐng)大家,添加上之前遺漏的功能,讓我們的圖片播放器更加完善。
這次的程序開(kāi)發(fā)將完全基于上一次的代碼,如果有朋友還未看過(guò)上篇文章,請(qǐng)先閱讀Android實(shí)現(xiàn)圖片滾動(dòng)和頁(yè)簽控件功能的實(shí)現(xiàn)代碼。
既然是要加入自動(dòng)播放的功能,那么就有一個(gè)非常重要的問(wèn)題需要考慮。如果當(dāng)前已經(jīng)滾動(dòng)到了最后一張圖片,應(yīng)該怎么辦?由于我們目前的實(shí)現(xiàn)方案是,所有的圖片都按照布局文件里面定義的順序橫向排列,然后通過(guò)偏移第一個(gè)圖片的leftMargin,來(lái)決定顯示哪一張圖片。因此當(dāng)圖片滾動(dòng)在最后一張時(shí),我們可以讓程序迅速地回滾到第一張圖片,然后從頭開(kāi)始滾動(dòng)。這種效果和淘寶客戶端是有一定差異的(淘寶并沒(méi)有回滾機(jī)制,而是很自然地由最后一張圖片滾動(dòng)到第一張圖片),我也研究過(guò)淘寶圖片滾動(dòng)器的實(shí)現(xiàn)方法,并不難實(shí)現(xiàn)。但是由于我們是基于上次的代碼進(jìn)行開(kāi)發(fā)的,方案上無(wú)法實(shí)現(xiàn)和淘寶客戶端一樣的效果,因此這里也就不追求和它完全一致了,各有風(fēng)格也挺好的。
好了,現(xiàn)在開(kāi)始實(shí)現(xiàn)功能,首先是打開(kāi)SlidingSwitcherView,在里面加入一個(gè)新的AsyncTask,專門(mén)用于回滾到第一張圖片:
class ScrollToFirstItemTask extends AsyncTask<Integer, Integer, Integer> {
@Override
protected Integer doInBackground(Integer... speed) {
int leftMargin = firstItemParams.leftMargin;
while (true) {
leftMargin = leftMargin + speed[0];
// 當(dāng)leftMargin大于0時(shí),說(shuō)明已經(jīng)滾動(dòng)到了第一個(gè)元素,跳出循環(huán)
if (leftMargin > 0) {
leftMargin = 0;
break;
}
publishProgress(leftMargin);
sleep(20);
}
return leftMargin;
}
@Override
protected void onProgressUpdate(Integer... leftMargin) {
firstItemParams.leftMargin = leftMargin[0];
firstItem.setLayoutParams(firstItemParams);
}
@Override
protected void onPostExecute(Integer leftMargin) {
firstItemParams.leftMargin = leftMargin;
firstItem.setLayoutParams(firstItemParams);
}
}
然后在SlidingSwitcherView里面加入一個(gè)新的方法:
/**
* 滾動(dòng)到第一個(gè)元素。
*/
public void scrollToFirstItem() {
new ScrollToFirstItemTask().execute(20 * itemsCount);
}
這個(gè)方法非常簡(jiǎn)單,就是啟動(dòng)了我們新增的ScrollToFirstItemTask,滾動(dòng)速度設(shè)定為20 * itemsCount,這樣當(dāng)我們需要滾動(dòng)的圖片數(shù)量越多,回滾速度就會(huì)越快。定義好這個(gè)方法后,只要在任意地方調(diào)用scrollToFirstItem這個(gè)方法,就可以立刻從當(dāng)前圖片回滾到第一張圖片了。
OK,然后我們要定義一個(gè)方法用于啟動(dòng)自動(dòng)播放功能。仍然是在SlidingSwitcherView中新增如下代碼:
/**
* 用于在定時(shí)器當(dāng)中操作UI界面。
*/
private Handler handler = new Handler();
/**
* 開(kāi)啟圖片自動(dòng)播放功能,當(dāng)滾動(dòng)到最后一張圖片的時(shí)候,會(huì)自動(dòng)回滾到第一張圖片。
*/
public void startAutoPlay() {
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (currentItemIndex == itemsCount - 1) {
currentItemIndex = 0;
handler.post(new Runnable() {
@Override
public void run() {
scrollToFirstItem();
refreshDotsLayout();
}
});
} else {
currentItemIndex++;
handler.post(new Runnable() {
@Override
public void run() {
scrollToNext();
refreshDotsLayout();
}
});
}
}
}, 3000, 3000);
}
我們可以看到,這個(gè)方法里啟用了一個(gè)定時(shí)器,每隔三秒就會(huì)執(zhí)行一次。然后在定時(shí)器的執(zhí)行邏輯里面進(jìn)行判斷當(dāng)前圖片是否是最后一張,如果不是最后一張就滾動(dòng)到下一張圖片,如果是最后一張就回滾到第一張圖片。其中需要注意,定時(shí)器中的代碼是在子線程中運(yùn)行的,而滾動(dòng)圖片操作和更新頁(yè)簽操作都是UI操作,因此需要放到Handler中去執(zhí)行。
之后只要在Activity創(chuàng)建的時(shí)候去調(diào)用SlidingSwitcherView的startAutoPlay方法,自動(dòng)播放功能就實(shí)現(xiàn)了?。?/p>
結(jié)束了?Naive!! 如果就這么結(jié)束了,怎么對(duì)得起大家的期待,如此簡(jiǎn)單的功能還要用一篇文章來(lái)講簡(jiǎn)直是弱爆了。
接下來(lái)才是今天的重點(diǎn),我們要使用自定義屬性來(lái)啟用自動(dòng)播放功能,這樣才能讓你更加接近高手,才能讓你更加玩轉(zhuǎn)Android。
那我們繼續(xù),在res/values目錄下新建一個(gè)attrs.xml文件,里面加入代碼:
<?xml version="1.0" encoding="UTF-8"?> <resources> <attr name="auto_play" forMymat="boolean" /> <declare-styleable name="SlidingSwitcherView"> <attr name="auto_play" /> </declare-styleable> </resources>
其中,auto_play是我們將要使用的屬性名,格式是布爾型。SlidingSwitcherView這個(gè)值可以隨意,主要在代碼中需要引用相應(yīng)的id。
然后重寫(xiě)SlidingSwitcherView的構(gòu)造函數(shù),在里面加入從布局文件中獲取自定義屬性的代碼:
public SlidingSwitcherView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingSwitcherView);
boolean isAutoPlay = a.getBoolean(R.styleable.SlidingSwitcherView_auto_play, false);
if (isAutoPlay) {
startAutoPlay();
}
a.recycle();
}
可以看到,我們?cè)跇?gòu)造函數(shù)中去獲取auto_play的值,如果為true,就調(diào)用startAutoPlay方法,從而啟用了自動(dòng)播放的功能。
接下來(lái)就是見(jiàn)證奇跡的時(shí)刻!讓我們打開(kāi)activity_main.xml,在里面加入兩行關(guān)鍵性代碼。在最外層的LinearLayout加入在我們自定義的com.example.viewswitcher.SlidingSwitcherView加入myattr:auto_play="true"。完整XML代碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:myattr="http://schemas.android.com/apk/res/com.example.viewswitcher" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:context=".MainActivity" > <com.example.viewswitcher.SlidingSwitcherView android:id="@+id/slidingLayout" myattr:auto_play="true" android:layout_width="fill_parent" android:layout_height="100dip" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/image1" /> <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/image2" /> <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/image3" /> <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/image4" /> </LinearLayout> <LinearLayout android:layout_width="60dip" android:layout_height="20dip" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="15dip" android:orientation="horizontal" > </LinearLayout> </com.example.viewswitcher.SlidingSwitcherView> </LinearLayout>
也就是說(shuō),我們只需要通過(guò)設(shè)定myattr:auto_play是等于true還是false,就可以決定是否啟用自動(dòng)播放功能,非常簡(jiǎn)單方便。
好了,今天的講解到此結(jié)束,有疑問(wèn)的朋友請(qǐng)?jiān)谙旅媪粞浴?/p>
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Android自定義Drawable之在Drawable中部指定透明區(qū)域方法示例
對(duì)于不同的屏幕密度、不同的設(shè)備方向,不同的語(yǔ)言和區(qū)域,都會(huì)涉及到備選 drawable 資源,下面這篇文章主要給你大家介紹了關(guān)于Android自定義Drawable之在Drawable中部指定透明區(qū)域的相關(guān)資料,需要的朋友可以參考下2018-07-07
Android實(shí)現(xiàn)GridView中ImageView動(dòng)態(tài)變換的方法
這篇文章主要介紹了Android實(shí)現(xiàn)GridView中ImageView動(dòng)態(tài)變換的方法,以實(shí)例形式較為詳細(xì)的分析了GridView中ImageView動(dòng)態(tài)變換的頁(yè)面布局及功能實(shí)現(xiàn)相關(guān)技巧,需要的朋友可以參考下2015-10-10
Android之Intent附加數(shù)據(jù)的兩種實(shí)現(xiàn)方法
這篇文章主要介紹了Android之Intent附加數(shù)據(jù)的兩種實(shí)現(xiàn)方法,以實(shí)例形式較為詳細(xì)的分析了添加數(shù)據(jù)到Intent的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Android4.0平板開(kāi)發(fā)之隱藏底部任務(wù)欄的方法
這篇文章主要介紹了Android4.0平板開(kāi)發(fā)之隱藏底部任務(wù)欄的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android隱藏于顯示底部任務(wù)欄的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Kotlin基礎(chǔ)學(xué)習(xí)之位運(yùn)算
一提起位運(yùn)算,人們往往想到它的高效性,無(wú)論是嵌入式編程還是優(yōu)化系統(tǒng)的核心代碼,適當(dāng)?shù)倪\(yùn)用位運(yùn)算總是一種迷人的手段,下面這篇文章主要給大家介紹了關(guān)于Kotlin基礎(chǔ)學(xué)習(xí)之位運(yùn)算的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-11-11
Android?Room數(shù)據(jù)庫(kù)加密詳解
這篇文章主要為大家詳細(xì)介紹了Android?Room數(shù)據(jù)庫(kù)加密,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Android 登錄處理簡(jiǎn)單實(shí)例(源碼下載)
這篇文章主要介紹了Android 登錄處理簡(jiǎn)單實(shí)例(源碼下載)的相關(guān)資料,需要的朋友可以參考下2017-03-03

