前段時(shí)間,Google公布了Android開發(fā)最佳實(shí)踐的一系列課程湃密,涉及到一些平時(shí)開發(fā)過(guò)程中應(yīng)該保持的良好習(xí)慣以及如何使用最新的Android Design Support Library來(lái)快速實(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無(wú)法正常工作。一旦發(fā)生隱式Intent找不到合適的調(diào)用組件的情況初坠,系統(tǒng)就會(huì)拋出ActivityNotFoundException
的異常和簸,如果我們的應(yīng)用沒有對(duì)這個(gè)異常做任何處理彭雾,那應(yīng)用就會(huì)發(fā)生Crash碟刺。
預(yù)防這個(gè)問(wèn)題的最佳解決方案是在發(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兼容包來(lái)處理消息通知
為了解決Android系統(tǒng)版本差異導(dǎo)致的Notification兼容性問(wèn)題薯酝,Android官方提供了NotificationCompat
兼容類來(lái)幫助開發(fā)實(shí)現(xiàn)體驗(yàn)統(tǒng)一的Notification半沽。通常來(lái)說(shuō)爽柒,建立一個(gè)Notification至少會(huì)有三種元素:圖標(biāo),標(biāo)題者填,文本浩村。我們通常會(huì)使用如下的代碼來(lái)實(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可以支持展開顯示的模式怎燥,這樣一來(lái),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)限沒有獲取到的情況下诡延,需要通過(guò)shouldShowRequestPermissionRationable()
的判斷來(lái)決定如何給用戶進(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來(lái)自Android官方的兼容包夭谤,通過(guò)它可以告訴Android系統(tǒng)與其他的應(yīng)用,自己正在播放的內(nèi)容是什么以及自己支持哪些類型的播放控制:
在Android的官方培訓(xùn)課程中有介紹過(guò)關(guān)于Media Button Receiver的概念巫糙,Android系統(tǒng)會(huì)把來(lái)自藍(lán)牙控制器或者是耳機(jī)等其他設(shè)備的操作事件轉(zhuǎn)換成Media Button事件傳遞出來(lái)朗儒,如果我們的應(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之后,還需要通過(guò)MediaMetadataCompat
來(lái)傳遞播放的資料信息卵惦,通過(guò)PlaybackStateCompat
來(lái)傳遞播放的狀態(tài)信息颓哮。
做了上面那些操作之后,MediaSessionCompat的任務(wù)就算是完成了鸵荠。
5)使用Toolbar替代ActionBar
自從MaterialDesign開始冕茅,Android官方就開始使用Toolbar替代了原來(lái)的ActionBar,現(xiàn)在Toolbar已經(jīng)加入Support兼容包蛹找。Toolbar是一個(gè)相比起ActionBar更加豐富姨伤,更加靈活的組件,另外它的布局本身還是View Hierarchy的一部分庸疾,這就意味著可以對(duì)Toolbar執(zhí)行動(dòng)畫操作乍楚,增加點(diǎn)擊滑動(dòng)事件等等,甚至我們還可以在一個(gè)頁(yè)面里面加入兩個(gè)Toolbar届慈。
為了啟用Toolbar徒溪,首先要做的事情就是關(guān)閉當(dāng)前Activity的ActionBar。我們可以通過(guò)使得Activity的主題繼承Theme.AppCompat.NoActionBar
金顿,然后在對(duì)應(yīng)的XML布局文件中臊泌,添加類似下面的toolbar布局信息:
12345678
<!--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è)置:
12345678
@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)簽來(lái)設(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來(lái)實(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)很多兼容性問(wè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行為等等傲隶。國(guó)內(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文件:
[圖片上傳中馋劈。攻锰。。(25)]
android:checked
表示當(dāng)前選中的Item妓雾,會(huì)被系統(tǒng)Highlight出來(lái)娶吞。除了上面簡(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來(lái)提供內(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)航等等功能來(lái)更好的幫助用戶使用這些應(yīng)用。
為了確保你的應(yīng)用能夠被Android系統(tǒng)提供的輔助功能正常使用窍霞,需要做以下三個(gè)步驟的檢查:
Content Description:確保類似ImageView匠题,ImageButton,CheckBox等組件都包含了content descrption但金。
Focus Order:確保給布局里面的關(guān)鍵元素增加了Focus的指示順序韭山,只有這樣,輔助功能才能夠在指向?qū)Ш降臅r(shí)候幫助用戶按照指定的順序來(lái)聚焦界面元素冷溃。
Feedback Mechanisms:確保部分關(guān)鍵的操作有多個(gè)反饋盖淡,例如當(dāng)短信來(lái)的時(shí)候,既有聲音也有震動(dòng)凿歼,這樣才能夠確保聽力不好的用戶可以通過(guò)震動(dòng)的反饋來(lái)感知到響應(yīng)褪迟。
更多關(guān)于輔助功能的知識(shí)冗恨,請(qǐng)參考http://developer.android.com/guide/topics/ui/accessibility/checklist.html