轉(zhuǎn)載于 郭霖
現(xiàn)在已經(jīng)進(jìn)入了2018年,Android 8.0系統(tǒng)也逐漸開始普及起來了。三星今年推出的最新旗艦機(jī)Galaxy S9已經(jīng)搭載了Android 8.0系統(tǒng),緊接著小米、華為、OV等國(guó)產(chǎn)手機(jī)廠商即將推出的新年旗艦機(jī)也會(huì)搭載Android 8.0系統(tǒng)。因此,現(xiàn)在已經(jīng)是時(shí)候需要讓我們的應(yīng)用程序?qū)ndroid 8.0系統(tǒng)進(jìn)行適配了。
其實(shí)在去年Android 8.0系統(tǒng)剛推出的時(shí)候,我就仔細(xì)翻閱過Google官方的功能變更文檔。變更項(xiàng)著實(shí)不少,但是真正需要我們?nèi)ミM(jìn)行功能適配的地方卻并不多。總結(jié)了一下,最主要需要進(jìn)行適配的地方有兩處:應(yīng)用圖標(biāo)和通知欄。那么我們就分為上下兩篇來分別對(duì)這兩處功能適配進(jìn)行講解,先從應(yīng)用圖標(biāo)開始。
為什么要進(jìn)行應(yīng)用圖標(biāo)適配?
可能有些朋友覺得困惑,應(yīng)用圖標(biāo)這種東西從Android遠(yuǎn)古時(shí)代就已經(jīng)有了,而且功能格外的簡(jiǎn)單,就是放張圖片而已,這有什么好適配的呢?但實(shí)際上,在當(dāng)前Android環(huán)境下,應(yīng)用圖標(biāo)功能是極其混亂的。
如果說要講一講手機(jī)應(yīng)用圖標(biāo)的歷史,其實(shí)要從蘋果開始講起。在上世紀(jì)80年代,蘋果還在設(shè)計(jì)Lisa和Macintosh電腦的時(shí)候,喬布斯就是個(gè)圓角矩形的狂熱支持者。當(dāng)時(shí)蘋果的工程師寫出了一套絕妙的算法,可以在電腦上繪制出圓和橢圓,所有觀看者都被震驚了,除了喬布斯,因?yàn)閱滩妓褂X得圓和橢圓雖然也不錯(cuò),但是如果能繪制出帶圓角的矩形就更好了。當(dāng)時(shí)那位工程師覺得這是不可能實(shí)現(xiàn)的,而且也完全用不著圓角矩形,能滿足基本的繪圖需求就可以了。喬布斯憤怒地拉著他走了3條街,指出大街上各種應(yīng)用圓角矩形的例子,最后那位工程師第二天就做出了繪制圓角矩形的功能。
因此,在2007年一代iPhone誕生的時(shí)候,所有應(yīng)用程序的圖標(biāo)都毫不出乎意料地使用了圓角矩形圖標(biāo),即使是第三方應(yīng)用也被強(qiáng)制要求使用圓角矩形圖標(biāo),并且這一規(guī)則一直延續(xù)到了今天的iOS 11當(dāng)中,如下圖所示:
相反,Android系統(tǒng)在設(shè)計(jì)的時(shí)候就不喜歡蘋果這樣的封閉與強(qiáng)制,而是選擇了自由與開放,對(duì)應(yīng)用圖標(biāo)的形狀不做任何強(qiáng)制要求,開發(fā)者們可以自由進(jìn)行選擇:
可以看到,在Android上,應(yīng)用圖標(biāo)可以是方形、圓形、圓角矩形、或者是其他任意不規(guī)則圖形。
本來就是兩家公司不同的設(shè)計(jì)理念,也說不上孰高孰低。但由于Android操作系統(tǒng)是開源的,國(guó)內(nèi)一些手機(jī)廠商在定制操作系統(tǒng)的時(shí)候就把這一特性給改了。比如小米手機(jī),就選擇了向蘋果靠攏,強(qiáng)制要求應(yīng)用圖標(biāo)圓角化。如果某些應(yīng)用的圖標(biāo)不是圓角矩形的呢?小米系統(tǒng)會(huì)自動(dòng)給它加上一個(gè)圓角的效果,如下圖所示:
小米的這種做法看上去是向蘋果學(xué)習(xí),但實(shí)際上是相當(dāng)惡心的。因?yàn)檎l都可以看出來,這種自動(dòng)添加的圓角矩形非常丑,因此很多公司就索性直接將應(yīng)用的圖標(biāo)都設(shè)計(jì)成圓角矩形的,正好Android和iOS都用同一套圖標(biāo)還省事了。
但是這就讓Google不開心了,這不是變向強(qiáng)制要求開發(fā)者必須將圖標(biāo)設(shè)計(jì)成圓角矩形嗎?于是在去年的Google I/O大會(huì)上,Google點(diǎn)名批評(píng)了小米的這種做法,說其違反了Android自由和開放的理念。
除了變向強(qiáng)制要求應(yīng)用圖標(biāo)圓角化,小米的這種處理方式還有一個(gè)弊端,就是如果應(yīng)用圖標(biāo)的圓角弧度和小米系統(tǒng)要求的不同,那么會(huì)出現(xiàn)異常丑陋的效果:
看到這樣的應(yīng)用圖標(biāo),真的是一臉尷尬癥都要犯了。就因?yàn)檫@兩款應(yīng)用圖標(biāo)的圓角弧度設(shè)計(jì)得大于了小米系統(tǒng)要求的圓角弧度,就被自動(dòng)添加上了這樣丑陋的白邊。
問題是已經(jīng)存在了,那么應(yīng)該怎么解決呢?說實(shí)話,這確實(shí)是一個(gè)長(zhǎng)期以來都讓人頭疼的問題,Google多年來對(duì)此也是睜一只眼閉一只眼。終于在Android 8.0系統(tǒng)中,Google下定決心要好好整治一下Android應(yīng)用圖標(biāo)的規(guī)范性了,今天我們就來學(xué)習(xí)一下。
8.0系統(tǒng)的應(yīng)用圖標(biāo)適配
這個(gè)問題對(duì)于Google來說還是挺難解決的。因?yàn)镚oogle一直在強(qiáng)調(diào)自由與開放,那么小米強(qiáng)制要求所有應(yīng)用圖標(biāo)都必須圓角化也是人家的自由呀,你不準(zhǔn)人家這么干是不是本身就違背了自由和開放的理念呢?當(dāng)然我們?cè)谶@里討論這個(gè),有點(diǎn)像討論先有雞還是先有蛋的感覺,不過Google還是想出了一套完美的解決方案。
從Android 8.0系統(tǒng)開始,應(yīng)用程序的圖標(biāo)被分為了兩層:前景層和背景層。也就是說,我們?cè)谠O(shè)計(jì)應(yīng)用圖標(biāo)的時(shí)候,需要將前景和背景部分分離,前景用來展示應(yīng)用圖標(biāo)的Logo,背景用來襯托應(yīng)用圖標(biāo)的Logo。需要注意的是,背景層在設(shè)計(jì)的時(shí)候只允許定義顏色和紋理,但是不能定義形狀。
那么應(yīng)用圖標(biāo)的形狀由誰來定義呢?Google將這個(gè)權(quán)利就交給手機(jī)廠商了。不是有些手機(jī)廠商喜歡學(xué)習(xí)蘋果的圓角圖標(biāo)嗎?沒問題,由于應(yīng)用圖標(biāo)的設(shè)計(jì)分為了兩層,手機(jī)廠商只需要在這兩層之上再蓋上一層mask,這個(gè)mask可以是圓角矩形、圓形或者是方形等等,視具體手機(jī)廠商而定,就可以瞬間讓手機(jī)上的所有應(yīng)用圖標(biāo)都變成相同的規(guī)范。原理示意圖如下:
可以看到,這里背景層是一張藍(lán)色的網(wǎng)格圖,前景層是一張Android機(jī)器人Logo圖,然后蓋上一層圓形的mask,最終就裁剪出了一張圓形的應(yīng)用圖標(biāo)。
我一定要適配嗎?
有些朋友可能會(huì)覺得這種分成兩層的應(yīng)用圖標(biāo)設(shè)計(jì)太過于麻煩,不適配可以嗎?也有些朋友可能會(huì)說,自己的APP并沒有做過應(yīng)用圖標(biāo)適配,在Android 8.0手機(jī)上也照樣跑得好好的。
事實(shí)上,這個(gè)新功能Google是準(zhǔn)備讓它慢慢過渡的,而不是一次性就強(qiáng)推給所有的開發(fā)者。如果你的APP中的targetSdkVersion是低于26的,那么就可以不用進(jìn)行應(yīng)用圖標(biāo)適配,Android 8.0系統(tǒng)仍然是向下兼容的。但是如果你將targetSdkVersion指定到了26或者更高,那么Android系統(tǒng)就會(huì)認(rèn)為你的APP已經(jīng)做好了8.0系統(tǒng)的適配工作,當(dāng)然包括了應(yīng)用圖標(biāo)的適配。
如果你將targetSdkVersion指定到了26,但是卻沒有進(jìn)行Android 8.0系統(tǒng)的應(yīng)用圖標(biāo)適配,那么會(huì)出現(xiàn)什么樣的效果呢?這里我舉幾個(gè)反面示例:
這是Google Pixel手機(jī)上的截圖,操作系統(tǒng)是Android 8.0。可以看到,這兩個(gè)應(yīng)用的圖標(biāo)都非常奇怪,本來設(shè)計(jì)的都是一個(gè)圓角矩形的圖標(biāo),但是卻又在外面套上了一個(gè)白色的圓圈。為什么會(huì)出現(xiàn)這種情況呢?就是因?yàn)檫@兩個(gè)應(yīng)用都將targetSdkVersion指定到了26以上,但是卻又沒有做8.0系統(tǒng)的應(yīng)用圖標(biāo)適配,而Pixel手機(jī)設(shè)定的mask是圓形的,所以就自動(dòng)在應(yīng)用圖標(biāo)的外層套了一個(gè)白色的圓圈。
由此可以看出,愛奇藝和餓了么這兩款應(yīng)用都是沒有在Pixel上進(jìn)行兼容性測(cè)試的。不過考慮到它們都是只在國(guó)內(nèi)市場(chǎng)提供服務(wù),因此也情有可原。
當(dāng)然了,國(guó)內(nèi)的Android 8.0手機(jī)很快也要開始普及了,我相信沒有任何人會(huì)希望自己的APP也出現(xiàn)上述的效果,因此下面我們就來開始具體學(xué)習(xí),如何進(jìn)行8.0系統(tǒng)的應(yīng)用圖標(biāo)適配。
新建一個(gè)項(xiàng)目
如果有人問我8.0系統(tǒng)應(yīng)用圖標(biāo)適配到底難不難?這里我會(huì)回答,一點(diǎn)都不難。相信所有看完這篇文章的人立馬就能學(xué)會(huì),但前提是你需要有一個(gè)好的工具——Android Studio 3.0或更高版本。
很高興告訴大家,Android Studio 3.0中已經(jīng)內(nèi)置了8.0系統(tǒng)應(yīng)用圖標(biāo)適配的功能,如果你已經(jīng)安裝了Android Studio 3.0的話,那么恭喜你,你已經(jīng)成功了百分之九十了。如果你還在用老版的Android Studio,那么趕快去升級(jí)一下,然后再接著看這篇文章。
好的,那么現(xiàn)在我們就用Android Studio 3.0來新建一個(gè)項(xiàng)目,就叫它IconTest吧。
創(chuàng)建好項(xiàng)目之后,打開app/build.gradle文件檢查一下,確保targetSdkVersion已經(jīng)指定到了26或者更高,如下所示:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.icontest"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
可以看到,這里我在創(chuàng)建新項(xiàng)目的時(shí)候默認(rèn)targetSdkVersion就是26,如果你是低于26的話,說明你的Android SDK有些老了,最好還是更新一下。當(dāng)然如果你懶得更新也沒關(guān)系,手動(dòng)把它改成26就可以了。
接下來打開AndroidManifest.xml文件,代碼如下所示:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.icontest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
這里我們需要關(guān)注的點(diǎn)是android:icon這個(gè)屬性,通過這個(gè)屬性,我們將應(yīng)用的圖標(biāo)指定為了mipmap目錄下的ic_launcher文件。另外大家可能注意到還有一個(gè)android:roundIcon屬性,這是一個(gè)只適用在Android 7.1系統(tǒng)上的過渡版本,很快就被8.0系統(tǒng)的應(yīng)用圖標(biāo)適配所替代了,我們不用去管它。
剛才說了,應(yīng)用圖標(biāo)被指定為了mipmap目錄下的ic_launcher文件,那么我們快去看下這個(gè)文件吧:
這里雖然目錄很多,但是相信任何只要是入了門的Android開發(fā)者都能看得懂。唯一需要我們留意的就是mipmap-anydpi-v26這個(gè)目錄,這個(gè)目錄表示什么意思呢?就是Android 8.0或以上系統(tǒng)的手機(jī),都會(huì)使用這個(gè)目錄下的ic_launcher來作為圖標(biāo)。
你會(huì)發(fā)現(xiàn),mipmap-anydpi-v26目錄下的ic_launcher并不是一張圖片,而是一個(gè)XML文件,我們打開這個(gè)文件看一下,代碼如下所示:
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
這是一個(gè)8.0系統(tǒng)應(yīng)用圖標(biāo)適配的標(biāo)準(zhǔn)寫法,在<adaptive-icon>標(biāo)簽中定義一個(gè)<background>標(biāo)簽用于指定圖標(biāo)的背景層,定義一個(gè)<foreground>標(biāo)簽用于指定圖標(biāo)的前景層。
那么我們分別來看一下背景層和前景層分別都是些什么內(nèi)容吧,首先打開ic_launcher_background文件,內(nèi)容如下圖所示:
這是一個(gè)使用SVG格式繪制出來的帶紋理的底圖。當(dāng)然如果你看不懂這里面的代碼也沒有關(guān)系,因?yàn)槲乙部床欢VG格式的圖片都是使用AI、PS等圖像編輯軟件制作之后導(dǎo)出的,基本沒有人可以手工編寫SVG圖片。
當(dāng)然,背景層并不是一定要用SVG格式的圖片,你也可以使用普通的PNG、JPG等格式的圖片,甚至是直接指定一個(gè)背景色都可以。
看完了背景層接著我們來看前景層,打開ic_launcher_foreground文件,內(nèi)容如下所示:
類似地,這里也是使用SVG格式繪制出了一個(gè)Android機(jī)器人的Logo,并且這個(gè)機(jī)器人還是帶投影效果的。當(dāng)然了,前景層我們也是可以使用PNG、JPG等格式的圖片的,待會(huì)兒會(huì)進(jìn)行演示。
好的,現(xiàn)在已經(jīng)把應(yīng)用圖標(biāo)相關(guān)部分的代碼都解釋完了,那么這樣一個(gè)剛剛創(chuàng)建完成的空項(xiàng)目運(yùn)行起來到底會(huì)是什么樣的效果呢?我們跑一下看看就知道了,如下圖所示:
可以看到,這就是一個(gè)前景層蓋在背景層上,然后再被圓形mask進(jìn)行裁剪之后的效果。
好的,那么現(xiàn)在剩下的問題就是,我們?nèi)绾尾拍軐?duì)自己的應(yīng)用圖標(biāo)在Android 8.0系統(tǒng)上進(jìn)行適配?
開始適配
看到愛奇藝的8.0系統(tǒng)應(yīng)用圖標(biāo)適配工作做得這么差,我就準(zhǔn)備拿愛奇藝來做為例子了,我們一起來幫愛奇藝的Android版做個(gè)漂亮的應(yīng)用圖標(biāo)適配吧。
那么很顯然,根據(jù)8.0系統(tǒng)的應(yīng)用圖標(biāo)設(shè)計(jì),我們需要準(zhǔn)備一個(gè)前景層和一個(gè)背景層才行。
前景層也就是愛奇藝的Logo了,這里我通過Photoshop把愛奇藝的Logo圖取了出來。
由于這是一張背景透明的圖片,如果直接貼到文章里面就一片白色,啥也看不見了,于是我只好在文章里貼了一張帶灰色背景的圖片。如果大家需要獲取愛奇藝這張前景圖的原圖,可以點(diǎn)擊最下方的 閱讀原文 獲取。
解決了前景層,接下來我們來看背景層。其實(shí)背景層比前景層就簡(jiǎn)單多了,一般如果沒有什么特殊需求的話,背景層直接使用某種純色就可以了。
這里我用Photoshop吸取了一下愛奇藝原始應(yīng)用圖標(biāo)的背景色,值是#04ca00。當(dāng)然,愛奇藝的背景色并不是完全的純色,而是有細(xì)微的顏色漸變的。不過這里我們只是舉例講解而已,就不追究這些細(xì)節(jié)了。
那么現(xiàn)在前景層和背景層都準(zhǔn)備好了,接下來我們正式開始進(jìn)行8.0系統(tǒng)的應(yīng)用圖標(biāo)適配。重新回到IconTest項(xiàng)目當(dāng)中,然后按下Windows:Ctrl+Shift+A / Mac:command+shft+A 快捷鍵,并輸入Image Asset,如下所示:
點(diǎn)擊回車鍵打開Asset Studio編輯器,在這里就可以進(jìn)行應(yīng)用圖標(biāo)適配了。
這個(gè)Asset Studio編輯器非常簡(jiǎn)單好用,一學(xué)就會(huì)。左邊是操作區(qū)域,右邊是預(yù)覽區(qū)域。
先來看操作區(qū)域,第一行的Icon Type保持默認(rèn)就可以了,表示同時(shí)創(chuàng)建兼容8.0系統(tǒng)以及老版本系統(tǒng)的應(yīng)用圖標(biāo)。第二行的Name用于指定應(yīng)用圖標(biāo)的名稱,這里也保持默認(rèn)即可。接下來的三個(gè)頁簽,F(xiàn)oreground Layer用于編輯前景層,Background Layer用于編輯背景層,Legacy用于編輯老版本系統(tǒng)的圖標(biāo)。
再來看預(yù)覽區(qū)域,這個(gè)就十分簡(jiǎn)單了,用于預(yù)覽應(yīng)用圖標(biāo)的最終效果。在預(yù)覽區(qū)域中給出了可能生成的圖標(biāo)形狀,包括圓形、圓角矩形、方形等等。注意每個(gè)預(yù)覽圖標(biāo)中都有一個(gè)圓圈,這個(gè)圓圈叫作安全區(qū)域,必須要保證圖標(biāo)的前景層完全處于安全區(qū)域當(dāng)中才行,否則可能會(huì)出現(xiàn)圖標(biāo)被手機(jī)廠商的mask裁剪掉的情況。
為了大家能夠更加直觀地看到操作,這里我使用一張GIF圖來演示操作的過程:
最終,Android Studio會(huì)自動(dòng)幫我們生成適配8.0系統(tǒng)的應(yīng)用圖標(biāo),以及適配老版本系統(tǒng)的應(yīng)用圖標(biāo),我們甚至一行代碼都不用寫,一切工作就已經(jīng)完成了。感興趣的朋友可以自己到mipmap目錄下面去觀察一下Android Studio幫我們生成了哪些東西,這里就不帶著大家一一去看了。
最后,讓我們來運(yùn)行一下程序,并且和正版愛奇藝的應(yīng)用圖標(biāo)放在一起對(duì)比一下吧:
可以看到,做過8.0系統(tǒng)應(yīng)用圖標(biāo)適配之后,效果明顯要好看太多了,也希望愛奇藝的官方APP也能早日完成適配吧。