(轉(zhuǎn))Android開發(fā)最佳實(shí)踐

摘自hukai blog

前段時(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的解釋以及用法如下:

android_dev_patterns_implicit_intent

然后這個(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功能:


android_dev_patterns_notification_base

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


android_dev_patterns_notification_base_show

為了給上面的Notification添加點(diǎn)擊之后的響應(yīng)效果占哟,我們還需要構(gòu)造一個(gè)PendingIntent
作為contentIntent心墅,例如:
PendingIntent intent = xxx;builder.setContentIntent(intent);

為了使得Notification更加的具有辨識(shí)度,我們還有可能做如下的設(shè)置:

android_dev_patterns_notification_set_large

從Android 4.1開始榨乎,Notification可以支持展開顯示的模式怎燥,這樣一來(lái),Notification就演變出了下面4種不同的風(fēng)格樣式:
android_dev_patterns_notification_4_styles

Notification還提供了快捷操作的功能蜜暑,如下圖所示:
android_dev_patterns_notification_set_action_show
android_dev_patterns_notification_set_action

除了顯示在手機(jī)上的Notification铐姚,我們還可以給Notification分別設(shè)置在Wearable,Auto上的不同表現(xiàn)行為肛捍,例如針對(duì)可穿戴設(shè)備上顯示Notification隐绵,我們可以如下的設(shè)置:
android_dev_patterns_notification_wearable

關(guān)于更多的Wearable上的Notification相關(guān)的知識(shí),還可以參考Pages of ContentStackable 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)限的操作筛璧。

android_dev_patterns_permission_check

處理權(quán)限申請(qǐng)的結(jié)果:申請(qǐng)權(quán)限之后,我們需要處理申請(qǐng)的響應(yīng)結(jié)果惹恃,分別處理權(quán)限申請(qǐng)成功與失敗的情況

android_dev_patterns_permission_response

4)使用MediaSessionCompat操作音樂的播放
MediaSessionCompat來(lái)自Android官方的兼容包夭谤,通過(guò)它可以告訴Android系統(tǒng)與其他的應(yīng)用,自己正在播放的內(nèi)容是什么以及自己支持哪些類型的播放控制:
android_dev_patterns_media_session

在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)行控制處理乏悄。
android_dev_patterns_media_receiver

基于上面的認(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è)置激活规求。
android_dev_patterns_media_usage

搭建好了MediaSessionCompat之后,還需要通過(guò)MediaMetadataCompat
來(lái)傳遞播放的資料信息卵惦,通過(guò)PlaybackStateCompat
來(lái)傳遞播放的狀態(tài)信息颓哮。
android_dev_patterns_media_set

做了上面那些操作之后,MediaSessionCompat的任務(wù)就算是完成了鸵荠。
android_dev_patterns_media_done

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猪狈,官方還有這樣一段描述:

android_dev_patterns_appbar_des

使用AppBarLayout需要注意下面幾個(gè)要點(diǎn):
首先,AppBarLayout必須作為CoordinatorLayout
的直接子View
其次辩恼,在AppBarLayout里面必須包含一個(gè)ToolBar
最后雇庙,在CoordinatorLayout里面可以添加那些可以滑動(dòng)的組件谓形,例如RecyclerView

一個(gè)標(biāo)準(zhǔn)的布局文件應(yīng)該是類似下面結(jié)構(gòu)的:


android_dev_patterns_appbar_scroll_xml

我們需要注意,在Toolbar里面設(shè)置的layout_scrollFlags會(huì)影響到滑動(dòng)之后的顯示效果状共,請(qǐng)看下面的具體解釋:


android_dev_patterns_appbar_scroll_flag

7)使用SearchView來(lái)實(shí)現(xiàn)搜索功能
關(guān)于在使用搜索的時(shí)候及時(shí)顯示給用戶的候選詞套耕,會(huì)需要根據(jù)數(shù)據(jù)的類型以及具體的情況做不同的處理谁帕,這里先暫時(shí)不討論那一塊的內(nèi)容峡继。
android_dev_patterns_searchview_show

android_dev_patterns_searchview_tips

上面的圖示已經(jīng)清楚的演示了使用SearchView處理搜索的通常情況,關(guān)于如何實(shí)現(xiàn)這個(gè)功能匈挖,需要做到以下幾個(gè)步驟:
在Menu的XML文件中碾牌,聲明使用SearchView
android_dev_patterns_searchview_xml

在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ù)邏輯

android_dev_patterns_searchview_code

至此择膝,其實(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脖卖。
android_dev_patterns_navigation_show

實(shí)現(xiàn)這樣的一個(gè)功能乒省,我們需要在XML中寫下類似下面的布局文件
android_dev_patterns_navigation_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è)置:
android_dev_patterns_navigation_click

除了點(diǎn)擊菜單事件机断,我們還需要處理整個(gè)側(cè)滑菜單的打開與關(guān)閉事件,當(dāng)我們給DrawerLayout設(shè)置了setDrawerListener之后绣夺,可以得到下面兩個(gè)回調(diào):
android_dev_patterns_navigation_drawer_event

大多數(shù)時(shí)候吏奸,側(cè)滑菜單都是從左到右滑出的,但是我們也可以做到從右往左滑出陶耍,只需要在DrawerLayout的菜單布局LinearLayout里面修改一下margin的相關(guān)屬性即可:
android_dev_patterns_navigation_right

9)Tabs and ViewPager
android_dev_patterns_viewpager_show

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代碼如下:
android_dev_patterns_viewpager_code

為了實(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但金。

android_dev_patterns_accessible_content

Focus Order:確保給布局里面的關(guān)鍵元素增加了Focus的指示順序韭山,只有這樣,輔助功能才能夠在指向?qū)Ш降臅r(shí)候幫助用戶按照指定的順序來(lái)聚焦界面元素冷溃。

android_dev_patterns_accessible_focus_order
[圖片上傳中钱磅。。似枕。(35)]
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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市味赃,隨后出現(xiàn)的幾起案子掀抹,更是在濱河造成了極大的恐慌,老刑警劉巖心俗,帶你破解...
    沈念sama閱讀 223,002評(píng)論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傲武,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡另凌,警方通過(guò)查閱死者的電腦和手機(jī)谱轨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門戒幔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吠谢,“玉大人,你說(shuō)我怎么就攤上這事诗茎」し唬” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評(píng)論 0 365
  • 文/不壞的土叔 我叫張陵敢订,是天一觀的道長(zhǎng)王污。 經(jīng)常有香客問(wèn)我,道長(zhǎng)楚午,這世上最難降的妖魔是什么昭齐? 我笑而不...
    開封第一講書人閱讀 60,237評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮矾柜,結(jié)果婚禮上阱驾,老公的妹妹穿的比我還像新娘。我一直安慰自己怪蔑,他們只是感情好里覆,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缆瓣,像睡著了一般喧枷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弓坞,一...
    開封第一講書人閱讀 52,821評(píng)論 1 314
  • 那天隧甚,我揣著相機(jī)與錄音,去河邊找鬼渡冻。 笑死戚扳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的菩帝。 我是一名探鬼主播咖城,決...
    沈念sama閱讀 41,236評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼茬腿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了宜雀?” 一聲冷哼從身側(cè)響起切平,我...
    開封第一講書人閱讀 40,196評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辐董,沒想到半個(gè)月后悴品,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡简烘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評(píng)論 3 343
  • 正文 我和宋清朗相戀三年苔严,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孤澎。...
    茶點(diǎn)故事閱讀 40,928評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡届氢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出覆旭,到底是詐尸還是另有隱情退子,我是刑警寧澤,帶...
    沈念sama閱讀 36,583評(píng)論 5 351
  • 正文 年R本政府宣布型将,位于F島的核電站寂祥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏七兜。R本人自食惡果不足惜丸凭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腕铸。 院中可真熱鬧惜犀,春花似錦、人聲如沸恬惯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)酪耳。三九已至浓恳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碗暗,已是汗流浹背颈将。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留言疗,地道東北人晴圾。 一個(gè)月前我還...
    沈念sama閱讀 49,378評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像噪奄,于是被迫代替她去往敵國(guó)和親死姚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子人乓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容