1仅讽、Android逐幀動(dòng)畫(huà)的實(shí)現(xiàn)
逐幀動(dòng)畫(huà),顧名思義媳板,就是用一張張圖片作為一幀幀咳焚,然后連續(xù)播放作為動(dòng)畫(huà)。
這種動(dòng)畫(huà)的實(shí)現(xiàn)非常簡(jiǎn)單:準(zhǔn)備好每一幀的圖片放到drawable文件夾下吴攒,寫(xiě)一個(gè)animation-list的xml放到drawable文件夾(不是anim文件夾U懦!M菡)下署惯,就像這樣
frame_animation_demo.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/第一幀" android:duration="200" />
<item android:drawable="@drawable/第二幀" android:duration="200" />
<item android:drawable="@drawable/第三幀" android:duration="200" />
...
<item android:drawable="@drawable/第n幀" android:duration="200" />
</animation-list>
其中的oneshot參數(shù)是表明這個(gè)動(dòng)畫(huà)是否只執(zhí)行一遍,true為只執(zhí)行一遍镣隶,false為無(wú)限循環(huán)執(zhí)行直到手動(dòng)stop或手動(dòng)替換掉這個(gè)資源极谊。
然后就可以在布局的xml中把這個(gè)xml作為一個(gè)drawable設(shè)置到某個(gè)View的background那里。
demo_layout.xml
...
android:background="@drawable/frame_animation_demo"
...
然后要啟動(dòng)和停止動(dòng)畫(huà)的話則直接在Java代碼中取到對(duì)應(yīng)的View安岂,然后再通過(guò)取得背景drawable轻猖,強(qiáng)轉(zhuǎn)為AnimationDrawable,然后調(diào)用對(duì)應(yīng)的start方法和stop方法即可域那。
需要注意的是咙边,stop被調(diào)用后,這個(gè)動(dòng)畫(huà)則是立即停止在當(dāng)前展示的幀次员,而不是停止在第n幀败许。
此外,不要在Activity的onCreate回調(diào)中調(diào)用AnimationDrawable的start方法淑蔚,因?yàn)閛nCreate時(shí)這個(gè)AnimationDrawable還沒(méi)有完整地attach上即將要展示的window市殷,如果希望Activity一出現(xiàn)時(shí)就開(kāi)始輪播動(dòng)畫(huà),請(qǐng)?jiān)贏ctivity的 onWindowFocusChanged()方法中調(diào)用AnimationDrawable的start方法刹衫。
2醋寝、HandlerThread的退出
在HandlerThread類中,提供了兩個(gè)退出方法绪妹,quit()和quitSafely()甥桂。
區(qū)別在于quit()方法是直接把消息隊(duì)列里的消息全都回收,而quitSafely()則是只回收消息隊(duì)列里的在調(diào)用了quitSafely()之后的才產(chǎn)生的消息邮旷,確保在調(diào)用之前產(chǎn)生的消息都能投遞完成黄选。
所以在退出時(shí)最好對(duì)系統(tǒng)版本進(jìn)行判別然后優(yōu)先調(diào)用quitSafely()來(lái)停止使用的HandlerThread。
3婶肩、Gradle腳本中办陷,對(duì)于字符串的雙引號(hào)和單引號(hào)的區(qū)別。
在Gradle腳本中律歼,對(duì)字符串的賦值有兩種民镜,一種是
str = "字符串"
另一種是
str = '字符串'
直觀的區(qū)別是,一個(gè)是雙引號(hào)险毁,另一個(gè)是單引號(hào)制圈。
而實(shí)質(zhì)上的區(qū)別是们童,雙引號(hào)的內(nèi)容會(huì)對(duì)$變量進(jìn)行轉(zhuǎn)義,而單引號(hào)的則不會(huì)進(jìn)行轉(zhuǎn)義鲸鹦。
例子:
build.gradle
...
def app_name = "Demo_App"
str_one = 'App_Name = $app_name'
str_two = "App_Name = $app_name"
System.out.println("str_one = ("+str_one+")");
System.out.println("str_two = ("+str_two+")");
...
上述腳本的輸出結(jié)果是:
str_one = (App_Name = $app_name)
str_two = (App_Name = Demo_App)
4慧库、Gradle腳本中,buildConfigField方法
在App打包時(shí)馋嗜,可能想在Java代碼中根據(jù)Gradle配置的不一樣來(lái)執(zhí)行不一樣的邏輯之類的齐板,那Gradle的ProductFlavor屬性中的buildConfigField方法就派上用場(chǎng)了。
這個(gè)方法接收的參數(shù)是三個(gè)String葛菇,所以如果傳入非String參數(shù)甘磨,那在Sync Gradle的時(shí)候IDE就會(huì)提示找不到對(duì)應(yīng)的buildConfigField方法。
例子:
build.gradle
...
productFlavors{
demo{
buildConfigField "boolean","mIsDemo","true"
}
}
...
這樣在demo類型的包中眯停,BuildConfig類中就會(huì)有mIsDemo的屬性值济舆。
那怎么把在Gradle腳本的前文中已定義好的參數(shù)放到buildConfigField中呢?配合本文第三條知識(shí)點(diǎn)即可庵朝。
5吗冤、ViewPager的狀態(tài)區(qū)別
ViewPager有三種狀態(tài)SCROLL_STATE_DRAGGING(用戶拖動(dòng)中)、SCROLL_STATE_IDLE(完全靜止)以及SCROLL_STATE_SETTLING(從拖動(dòng)中轉(zhuǎn)為完全靜止?fàn)顟B(tài)的過(guò)程中)九府。
常用的就SCROLL_STATE_DRAGGING和SCROLL_STATE_IDLE椎瘟。
例如拖動(dòng)的時(shí)候不響應(yīng)用戶的某些點(diǎn)擊操作,那么就可以添加一個(gè)OnPageChangeListener 侄旬,在onPageScrollStateChanged(int state)回調(diào)中肺蔚,對(duì)state為SCROLL_STATE_DRAGGING時(shí)就無(wú)視用戶點(diǎn)擊操作,在state為SCROLL_STATE_IDLE時(shí)再取消掉這個(gè)限制儡羔。
需要注意的是宣羊,即使是在ViewPager最邊上的一個(gè)Page了,再往邊界滑雖然滑不動(dòng)這個(gè)頁(yè)面汰蜘,但狀態(tài)也是會(huì)變?yōu)镾CROLL_STATE_DRAGGING仇冯,直到抬起手指了才會(huì)變回為SCROLL_STATE_IDLE狀態(tài)。