前段時(shí)間雷滋,Google公布了Android開發(fā)最佳實(shí)踐的一系列課程咖耘,涉及到一些平時(shí)開發(fā)過程中應(yīng)該保持的良好習(xí)慣以及如何使用最新的Android Design Support Library來快速實(shí)現(xiàn)官方推薦的Material Design樣式的應(yīng)用。下面是個(gè)人的學(xué)習(xí)摘要總結(jié)诱告,不對(duì)的地方請(qǐng)多多交流指點(diǎn),謝謝筑累!
1)注意對(duì)隱式Intent的運(yùn)行時(shí)檢查保護(hù)
類似打開相機(jī)崇决,發(fā)送圖片等隱式Intent,是并不一定能夠在所有的Android設(shè)備上都正常運(yùn)行键闺。例如打開相機(jī)的隱式Intent,如果系統(tǒng)相機(jī)應(yīng)用被關(guān)閉或者不存在相機(jī)應(yīng)用澈驼,又或者是相機(jī)應(yīng)用的某些權(quán)限被關(guān)閉等等情況都可能導(dǎo)致這個(gè)隱式的Intent無法正常工作辛燥。一旦發(fā)生隱式Intent找不到合適的調(diào)用組件的情況,系統(tǒng)就會(huì)拋出ActivityNotFoundException
的異常,如果我們的應(yīng)用沒有對(duì)這個(gè)異常做任何處理挎塌,那應(yīng)用就會(huì)發(fā)生Crash徘六。
預(yù)防這個(gè)問題的最佳解決方案是在發(fā)出這個(gè)隱式Intent之前調(diào)用resolveActivity
做檢查,關(guān)于這個(gè)API的解釋以及用法如下:
然后這個(gè)API的使用范例如下:
Intent intent = new Intent(Intent.ACTION_XXX);
ComponentName componentName = intent.resolveActivity(getPackageManager());
if(componentName != null) { String className = componentName.getClassName();}```
2)使用NotificationCompat兼容包來處理消息通知
為了解決Android系統(tǒng)版本差異導(dǎo)致的Notification兼容性問題榴都,Android官方提供了NotificationCompat
兼容類來幫助開發(fā)實(shí)現(xiàn)體驗(yàn)統(tǒng)一的Notification待锈。通常來說,建立一個(gè)Notification至少會(huì)有三種元素:圖標(biāo)缭贡,標(biāo)題炉擅,文本。我們通常會(huì)使用如下的代碼來實(shí)現(xiàn)一個(gè)基礎(chǔ)的Notification功能:

上面那段代碼阳惹,運(yùn)行時(shí)候的效果應(yīng)該如下所示:

為了給上面的Notification添加點(diǎn)擊之后的響應(yīng)效果谍失,我們還需要構(gòu)造一個(gè)PendingIntent
作為contentIntent,例如:
PendingIntent intent = xxx;builder.setContentIntent(intent);```
為了使得Notification更加的具有辨識(shí)度莹汤,我們還有可能做如下的設(shè)置:
從Android 4.1開始快鱼,Notification可以支持展開顯示的模式,這樣一來纲岭,Notification就演變出了下面4種不同的風(fēng)格樣式:
Notification還提供了快捷操作的功能抹竹,如下圖所示:
除了顯示在手機(jī)上的Notification,我們還可以給Notification分別設(shè)置在Wearable止潮,Auto上的不同表現(xiàn)行為窃判,例如針對(duì)可穿戴設(shè)備上顯示Notification,我們可以如下的設(shè)置:
關(guān)于更多的Wearable上的Notification相關(guān)的知識(shí)喇闸,還可以參考Pages of Content與Stackable Notifications
3)Android 6.0 Marshmallow的運(yùn)行時(shí)權(quán)限
Android 6.0開始引入了新的運(yùn)行時(shí)權(quán)限檢查授權(quán)機(jī)制袄琳,替代了之前安裝應(yīng)用的時(shí)候?qū)?quán)限進(jìn)行授權(quán)的方案。為了避免6.0及以上的機(jī)器運(yùn)行發(fā)生運(yùn)行時(shí)異常燃乍,我們需要做到至少以下5個(gè)步驟:
檢查系統(tǒng)版本號(hào):針對(duì)6.0以下的系統(tǒng)版本唆樊,默認(rèn)權(quán)限在安裝的時(shí)候已經(jīng)獲取到了,對(duì)于6.0開始的版本刻蟹,才需要做運(yùn)行時(shí)的權(quán)限檢查逗旁。
檢查申請(qǐng)的權(quán)限:在使用某個(gè)權(quán)限之前,需要檢查權(quán)限是否已經(jīng)獲取到了舆瘪。
解釋申請(qǐng)的權(quán)限:在權(quán)限沒有獲取到的情況下片效,需要通過
shouldShowRequestPermissionRationable()
的判斷來決定如何給用戶進(jìn)行提示。
執(zhí)行申請(qǐng)權(quán)限操作:前面判斷沒有獲取到權(quán)限英古,為了能夠讓功能順利執(zhí)行淀衣,我們會(huì)需要在代碼里面再次執(zhí)行申請(qǐng)此權(quán)限的操作。
處理權(quán)限申請(qǐng)的結(jié)果:申請(qǐng)權(quán)限之后哺呜,我們需要處理申請(qǐng)的響應(yīng)結(jié)果舌缤,分別處理權(quán)限申請(qǐng)成功與失敗的情況
4)使用MediaSessionCompat操作音樂的播放
MediaSessionCompat來自Android官方的兼容包,通過它可以告訴Android系統(tǒng)與其他的應(yīng)用某残,自己正在播放的內(nèi)容是什么以及自己支持哪些類型的播放控制:
在Android的官方培訓(xùn)課程中有介紹過關(guān)于Media Button Receiver的概念国撵,Android系統(tǒng)會(huì)把來自藍(lán)牙控制器或者是耳機(jī)等其他設(shè)備的操作事件轉(zhuǎn)換成Media Button事件傳遞出來,如果我們的應(yīng)用程序需要監(jiān)聽這些事件并做出相應(yīng)的響應(yīng)玻墅,就需要注冊(cè)MEDIA_BUTTON的action介牙,接收到這些事件之后,再傳遞給音樂播放模塊進(jìn)行控制處理澳厢。
基于上面的認(rèn)知环础,我們現(xiàn)在演示如何使用MediaSessionCompat,下面演示了如何構(gòu)造一個(gè)MediaSessionCompat以及構(gòu)造完之后通常需要做的三件事情:設(shè)置合理的flag剩拢,設(shè)置回調(diào)(在5.0開始會(huì)響應(yīng)onPlay线得,onPause等等回調(diào)),設(shè)置激活徐伐。
搭建好了MediaSessionCompat之后贯钩,還需要通過MediaMetadataCompat
來傳遞播放的資料信息,通過PlaybackStateCompat
來傳遞播放的狀態(tài)信息办素。
做了上面那些操作之后角雷,MediaSessionCompat的任務(wù)就算是完成了。
5)使用Toolbar替代ActionBar
自從MaterialDesign開始性穿,Android官方就開始使用Toolbar替代了原來的ActionBar勺三,現(xiàn)在Toolbar已經(jīng)加入Support兼容包。Toolbar是一個(gè)相比起ActionBar更加豐富需曾,更加靈活的組件狰闪,另外它的布局本身還是View Hierarchy的一部分,這就意味著可以對(duì)Toolbar執(zhí)行動(dòng)畫操作市埋,增加點(diǎn)擊滑動(dòng)事件等等谋旦,甚至我們還可以在一個(gè)頁面里面加入兩個(gè)Toolbar。
為了啟用Toolbar桑嘶,首先要做的事情就是關(guān)閉當(dāng)前Activity的ActionBar炊汹。我們可以通過使得Activity的主題繼承Theme.AppCompat.NoActionBar
,然后在對(duì)應(yīng)的XML布局文件中逃顶,添加類似下面的toolbar布局信息:
<!--Toolbar-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>```
在布局文件中添加Toolbar的信息之后讨便,需要啟動(dòng)Toolbar替代ActionBar,需要像下面一樣做設(shè)置:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);
setSupportActionBar(toolbar);
}```
關(guān)于更多Toolbar的細(xì)節(jié)以政,請(qǐng)參考官方文檔https://developer.android.com/reference/android/support/v7/widget/Toolbar.html
6)使用AppBarLayout并處理滑動(dòng)手勢(shì)
AppBarLayout是一個(gè)在android.support.design兼容包(這里有關(guān)于該兼容包的官方博客介紹http://android-developers.blogspot.com/2015/05/android-design-support-library.html)里面的新推出的組件霸褒,它是一個(gè)垂直方向的LinearLayout,包裝了很多Material Design的設(shè)計(jì)元素盈蛮,例如滑動(dòng)手勢(shì)的處理废菱。我們可以使用app:layout_scrollFlags
這樣的標(biāo)簽來設(shè)置滑動(dòng)的行為表現(xiàn)。關(guān)于App Bar,官方還有這樣一段描述:
使用AppBarLayout需要注意下面幾個(gè)要點(diǎn):
首先殊轴,AppBarLayout必須作為CoordinatorLayout
的直接子View
其次衰倦,在AppBarLayout里面必須包含一個(gè)ToolBar
最后,在CoordinatorLayout里面可以添加那些可以滑動(dòng)的組件旁理,例如RecyclerView
一個(gè)標(biāo)準(zhǔn)的布局文件應(yīng)該是類似下面結(jié)構(gòu)的:
我們需要注意樊零,在Toolbar里面設(shè)置的layout_scrollFlags會(huì)影響到滑動(dòng)之后的顯示效果,請(qǐng)看下面的具體解釋:
7)使用SearchView來實(shí)現(xiàn)搜索功能
關(guān)于在使用搜索的時(shí)候及時(shí)顯示給用戶的候選詞孽文,會(huì)需要根據(jù)數(shù)據(jù)的類型以及具體的情況做不同的處理驻襟,這里先暫時(shí)不討論那一塊的內(nèi)容。
上面的圖示已經(jīng)清楚的演示了使用SearchView處理搜索的通常情況芋哭,關(guān)于如何實(shí)現(xiàn)這個(gè)功能沉衣,需要做到以下幾個(gè)步驟:
在Menu的XML文件中,聲明使用SearchView
在onCreateOptionsMenu的回調(diào)函數(shù)里面獲取到SearchView减牺,并設(shè)置監(jiān)聽(請(qǐng)注意使用MenuItemCompat的那行代碼厢蒜,否則會(huì)出現(xiàn)很多兼容性問題,獲取不到這個(gè)View等等奇怪的BUG)烹植,在監(jiān)聽回調(diào)里面處理業(yè)務(wù)邏輯
至此斑鸦,其實(shí)就已經(jīng)實(shí)現(xiàn)了一個(gè)基礎(chǔ)的搜索功能。但是草雕,如果為了能夠讓自己的應(yīng)用的某些功能被Android系統(tǒng)的Search功能檢索到巷屿,我們就需要做更進(jìn)一步的操作,例如定義Searchable墩虹,實(shí)現(xiàn)一個(gè)SearchableActivity嘱巾,響應(yīng)系統(tǒng)的Search行為等等。國內(nèi)的應(yīng)用很少會(huì)去關(guān)注這個(gè)功能诫钓,這里就不展開了旬昭,感興趣點(diǎn)擊下面的鏈接進(jìn)一步學(xué)習(xí):https://developer.android.com/guide/topics/search/index.html
8)Navigation Drawer, DrawerLayout, NavigationView
Navigation Drawer是Material Design當(dāng)中很重要的一種設(shè)計(jì)元素,為了能夠快速的實(shí)現(xiàn)這種設(shè)計(jì)菌湃,Android在新的design support包里面為我們提供了DrawerLayout與NavigationView问拘。
實(shí)現(xiàn)這樣的一個(gè)功能,我們需要在XML中寫下類似下面的布局文件
在NavigationView中有兩個(gè)重要的標(biāo)簽惧所,app:headerLayout與app:menu骤坐,分別代表了拉出菜單的頂部布局與下面的菜單項(xiàng)列表。創(chuàng)建菜單項(xiàng)列表下愈,可以使用類似下面的MenuItem文件:
android:checked
表示當(dāng)前選中的Item纽绍,會(huì)被系統(tǒng)Highlight出來。除了上面簡(jiǎn)單的平鋪的菜單势似,還可以使用菜單嵌套的方式實(shí)現(xiàn)多級(jí)的菜單拌夏。關(guān)于點(diǎn)擊具體某個(gè)菜單的時(shí)候的監(jiān)聽與響應(yīng)僧著,需要做如下的設(shè)置:
除了點(diǎn)擊菜單事件,我們還需要處理整個(gè)側(cè)滑菜單的打開與關(guān)閉事件障簿,當(dāng)我們給DrawerLayout設(shè)置了setDrawerListener之后霹抛,可以得到下面兩個(gè)回調(diào):
大多數(shù)時(shí)候,側(cè)滑菜單都是從左到右滑出的卷谈,但是我們也可以做到從右往左滑出,只需要在DrawerLayout的菜單布局LinearLayout里面修改一下margin的相關(guān)屬性即可:
9)Tabs and ViewPager
ViewPager是Android上面實(shí)現(xiàn)橫向滑動(dòng)的基礎(chǔ)組件霞篡,能夠幫助大家迅速搭建類似上面圖示一樣的左右滑動(dòng)交互設(shè)計(jì)世蔗。ViewPager需要使用PagerAdapter來提供內(nèi)容,除了PagerAdpater朗兵,Android還提供了FragmentPagerAdpater與FragmentStatePagerAdapter污淋,前者會(huì)把所有的fragment都保存在內(nèi)存中,以便提高切換速度余掖,后者僅僅保留了fragment狀態(tài)信息寸爆,fragment還是會(huì)進(jìn)行正常的重建與銷毀。一個(gè)典型的使用demo代碼如下:
為了實(shí)現(xiàn)前面圖示的Tab與ViewPager的綁定盐欺,我們可以使用Android Design Support Library提供的TabLayout
赁豆,僅僅需要按照下面的代碼示例一樣把TabLayout與ViewPager做一個(gè)綁定,就能夠?qū)崿F(xiàn)左右滑動(dòng)與點(diǎn)擊Tab快速切換的功能:
關(guān)于Material Design里面的Tabs設(shè)計(jì)冗美,請(qǐng)?jiān)賲⒖?a target="_blank" rel="nofollow">http://www.google.com/design/spec/components/tabs.html以及官方Training課程里面的http://developer.android.com/training/implementing-navigation/lateral.html
10)Making Apps Accessible
為了照顧部分視力或者聽覺不好的用戶魔种,我們需要做一定的處理使得自己的應(yīng)用能夠被每一個(gè)可用。Android系統(tǒng)為了幫助應(yīng)用實(shí)現(xiàn)輔助功能粉洼,提供了諸如文本朗讀节预,觸感反饋,指向炳導(dǎo)航属韧,手勢(shì)導(dǎo)航等等功能來更好的幫助用戶使用這些應(yīng)用安拟。
為了確保你的應(yīng)用能夠被Android系統(tǒng)提供的輔助功能正常使用,需要做以下三個(gè)步驟的檢查:
Content Description:確保類似ImageView宵喂,ImageButton糠赦,CheckBox等組件都包含了content descrption。
Focus Order:確保給布局里面的關(guān)鍵元素增加了Focus的指示順序锅棕,只有這樣愉棱,輔助功能才能夠在指向?qū)Ш降臅r(shí)候幫助用戶按照指定的順序來聚焦界面元素。
Feedback Mechanisms:確保部分關(guān)鍵的操作有多個(gè)反饋哲戚,例如當(dāng)短信來的時(shí)候奔滑,既有聲音也有震動(dòng),這樣才能夠確保聽力不好的用戶可以通過震動(dòng)的反饋來感知到響應(yīng)顺少。
更多關(guān)于輔助功能的知識(shí)朋其,請(qǐng)參考
http://developer.android.com/guide/topics/ui/accessibility/checklist.html