Android 三種適配方案

適配緣由

做Android開(kāi)發(fā)一定會(huì)碰到適配這個(gè)問(wèn)題顶考,在Android世界里,Android設(shè)備太多了妖泄,手機(jī)驹沿,平板,TV蹈胡,手表等渊季,光其中的手機(jī)這一項(xiàng)就有眾多廠(chǎng)家發(fā)布的奇奇怪怪的手機(jī)朋蔫,不僅分辨率各有不同,就是手機(jī)尺寸也是一言難盡却汉,各種尺寸都有驯妄,更煩的是有的手機(jī)還在屏幕上搞個(gè)虛擬導(dǎo)航欄放在底部;廠(chǎng)家多也就算了合砂,由于Android系統(tǒng)的開(kāi)源青扔,任何廠(chǎng)家,個(gè)人翩伪,OEM廠(chǎng)商微猖,運(yùn)營(yíng)商都可以對(duì)Android進(jìn)行定制,修改成他們想要的樣子缘屹,這更加大了適配的難度(尤其是我在平時(shí)開(kāi)發(fā)中經(jīng)常會(huì)用到一些工程機(jī))凛剥;總之而言,Android的碎片化太嚴(yán)重了轻姿;不像ios適配機(jī)型有限犁珠,所以解決掉Android適配問(wèn)題是做一個(gè)好的APP的第一步

相關(guān)概念

在開(kāi)發(fā)過(guò)程中,UI給出的設(shè)計(jì)圖上的所有元素尺寸都是以px作為單位的互亮,但是我們?cè)趌ayout文件中定義相關(guān)View的長(zhǎng)寬是用dp作為單位來(lái)指定其值的盲憎,定義文字大小是用sp作為單位,還可能會(huì)涉及到屏幕尺寸胳挎,屏幕分辨率饼疙,屏幕像素密度dpi

這里說(shuō)到了四個(gè)單位:px dp sp dpi,還有屏幕尺寸及屏幕分辨率:

屏幕分辨率:指手機(jī)橫縱方向上的像素點(diǎn)數(shù)慕爬,比如常見(jiàn)的720 * 1280 窑眯,1080 * 1920,單位px医窿,1px=一個(gè)像素點(diǎn)磅甩,

屏幕尺寸:不是屏幕寬度,也不是長(zhǎng)度姥卢,而是屏幕的對(duì)角線(xiàn)長(zhǎng)度卷要,比如常見(jiàn)的5.0尺寸,5.5尺寸独榴,單位是英寸僧叉,1英寸=2.54厘米

dpi:全稱(chēng)dots per ich,也就是每英寸的像素點(diǎn)數(shù)(其實(shí)不是真正有多少像素點(diǎn)數(shù))棺榔,或者說(shuō)屏幕像素密度瓶堕;它是一個(gè)軟件上的概念,是在系統(tǒng)軟件上指定的單位尺寸的像素?cái)?shù)量症歇,它往往是寫(xiě)在系統(tǒng)出廠(chǎng)配置文件的一個(gè)固定值郎笆;我們可能還接觸過(guò)一個(gè)單位叫ppi谭梗,它也是像素密度,這個(gè)是物理上的概念宛蚓,它是客觀(guān)存在的不會(huì)改變激捏。dpi是軟件參考了物理像素密度后,人為指定的一個(gè)值凄吏,這樣保證了某一個(gè)區(qū)間內(nèi)的物理像素密度在軟件上都使用同一個(gè)值缩幸。這樣會(huì)有利于我們的UI適配;比如竞思,幾部相同分辨率不同尺寸的手機(jī)的ppi可能分別是是430,440,450,那么在Android系統(tǒng)中表谊,可能dpi會(huì)全部指定為480;ppi與屏幕尺寸和屏幕分辨率有關(guān)盖喷,它們的關(guān)系如下

dpi = \frac{\sqrt{ x^2 +y^2}}{屏幕尺寸}

px:這個(gè)大家容易理解爆办,也就是真實(shí)像素的單位,就跟s是時(shí)間秒的單位一樣

sp:全稱(chēng)scale-independent pixel课梳,也叫sip距辆,即獨(dú)立縮放像素,Android特有的用來(lái)描述文字大小的單位暮刃,建議使用12,14,18,20等偶數(shù)值跨算,避免奇數(shù)和小數(shù)造成精度的丟失問(wèn)題;為什么用這個(gè)不用dp呢椭懊?這是因?yàn)槲覀兛梢栽谑謾C(jī)系統(tǒng)設(shè)置中修改文字的大小诸蚕,如果使用dp單位,文字大小不會(huì)被改變氧猬;而使用sp會(huì)隨著修改而變化背犯;具體原因可參考sp與dp的區(qū)別

dp:全稱(chēng)Density-independent pixel 也叫dip,即獨(dú)立像素密度盅抚,它的一個(gè)特性就是與像素?zé)o關(guān)漠魏,或者說(shuō)與終端上的實(shí)際物理像素點(diǎn)無(wú)關(guān),是Android特有的用來(lái)描述View尺寸的單位妄均,保證同一個(gè)分辨率的圖片在不同分辨率的手機(jī)上保持同樣的視覺(jué)大兄隆(占用相識(shí)比例的空間)

比如同樣都是畫(huà)一條長(zhǎng)度是屏幕一半的線(xiàn),如果使用px作為計(jì)量單位丰包,那么在480x800分辨率手機(jī)上設(shè)置應(yīng)為240px禁熏;在320x480的手機(jī)上應(yīng)設(shè)置為160px,二者設(shè)置就不同了烫沙;如果使用dp為單位匹层,在這兩種分辨率下隙笆,160dp都顯示為屏幕一半的長(zhǎng)度锌蓄,原因在下方

在Android中升筏,規(guī)定以160dpi為基準(zhǔn),1dp=1px瘸爽;320dpi下您访,1dp = 2px,計(jì)算公式:px = dp * (dpi / 160)剪决,屏幕密度越大灵汪,1dp對(duì)應(yīng) 的像素點(diǎn)越多,如下表

這里還有一個(gè)東西沒(méi)有提柑潦,mdpi享言、hdpi、xhdpi渗鬼、xxhdpi览露、xxxhdpi等,它們是用來(lái)修飾Android中的mipmap(Eclipse中是drawable)文件夾及values文件夾譬胎,用來(lái)區(qū)分不同像素密度下的圖片和dimen值差牛,它們與dpi的關(guān)系如下



屏幕分辨率限定符

什么叫屏幕分辨率限定符呢?

我們知道市面上不同分辨率的手機(jī)太多太多了堰乔,而這種方案就是盡可能多的將其列舉出來(lái)偏化,在res目錄下面創(chuàng)建與各種分辨率一一對(duì)應(yīng)的values-xxx 文件夾;然后選定一種基準(zhǔn)分辨率镐侯,然后其它分辨率以該分辨率做參考侦讨,生成對(duì)應(yīng)的dimens文件,如圖:


假設(shè)設(shè)計(jì)圖上的一個(gè)控件的寬度為 720px苟翻,那么布局中就寫(xiě) android:layout_width="@dimen/x720" 搭伤,當(dāng)運(yùn)行程序的時(shí)候,系統(tǒng)會(huì)根據(jù)設(shè)備的分辨率去尋找對(duì)應(yīng)的 dimens.xml 文件袜瞬。例如運(yùn)行在分辨率為 1280x720 的設(shè)備上怜俐,系統(tǒng)會(huì)自動(dòng)找到對(duì)應(yīng)的 values-1280x720 文件夾下的 lay_x.xml 文件,由上圖可知 x720 對(duì)應(yīng)的值為

720.px邓尤,可鋪滿(mǎn)該屏幕寬度拍鲤。運(yùn)行在分辨率為 1920x1080 的設(shè)備上,系統(tǒng)會(huì)自動(dòng)找到對(duì)應(yīng)的 values-1920x1080 文件夾下的 lay_x.xml 文件汞扎,由上圖可知 x720 對(duì)應(yīng)的值為 1080.0px季稳,可鋪滿(mǎn)該屏幕寬度。這樣就達(dá)到了屏幕適配的要求

使用步驟

1澈魄、以設(shè)計(jì)圖最小寬度(單位為 dp)作為基準(zhǔn)值景鼠,生成所有設(shè)備對(duì)應(yīng)的 dimens.xml 文件

這些文件當(dāng)然不會(huì)手動(dòng)去寫(xiě),網(wǎng)上已經(jīng)有大神提供了自動(dòng)生成這些文件的插件ScreenMatch。但是這個(gè)插件還是有點(diǎn)問(wèn)題的:

默認(rèn)沒(méi)有適配最小寬度為 320dp 的設(shè)備铛漓。其實(shí)自己測(cè)試還是有很多設(shè)備最小寬度是 320dp 的溯香,所以需要加上。

最小寬度為 392.7272 與 411.4285 的手機(jī)不能達(dá)到完全適配浓恶。原因是該插件的默認(rèn)值都是取整的玫坛,即 392.7272 與 411.4285 在插件中寫(xiě)的是 392 與 411。

基于以上問(wèn)題包晰,我在該插件的源碼上優(yōu)化生成了新的插件ScreenMatch湿镀,由于插件庫(kù)已經(jīng)有原作者的插件了,所以我就不重復(fù)造輪子上傳到插件庫(kù)了伐憾,你直接用本地安裝的方式安裝即可勉痴。

工具使用步驟:

在 Android Studio 中安裝 ScreenMatch 插件

下載插件ScreenMatch到本地,點(diǎn)擊菜單欄上的 File -> Settings -> Plugins -> Install plugin from disk树肃,然后選擇我們剛剛下載的插件蚀腿,最后點(diǎn)擊 “OK”,重啟 Andorid Studio 即可扫外。如下圖所示:


2莉钙、在項(xiàng)目的默認(rèn) values 文件夾中需要一份 dimens.xml 文件


3、執(zhí)行生成

插件安裝好后筛谚,在項(xiàng)目的任意目錄或文件上右鍵磁玉,選擇 ScreenMatch 選項(xiàng)。如下圖:



4驾讲、通過(guò)上面的步驟就已經(jīng)生成了所有設(shè)備對(duì)應(yīng)的 dimens.xml 文件蚊伞。

根據(jù)設(shè)計(jì)圖填寫(xiě)最小寬度基準(zhǔn)值,并填寫(xiě)需要適配的設(shè)備最小寬度 dp 值

步驟 3 是以插件默認(rèn)的最小寬度基準(zhǔn)值為 360dp吮铭,適配的設(shè)備最小寬度為

320,360,384,392.7272,400,410,411.4285,432,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365(包含了平板和 TV )生成的文件时迫,但實(shí)際情況要根據(jù)設(shè)計(jì)圖和需求設(shè)置。

例如設(shè)計(jì)圖的最小寬度為 375dp谓晌,則需要更改最小寬度基準(zhǔn)值為 375dp掠拳。如果項(xiàng)目只需要適配手機(jī)的話(huà),適配的設(shè)備最小寬度保留 320,360,384,392.7272,400,410,411.4285,432,480 即可纸肉,若發(fā)現(xiàn)手機(jī)還有其他最小寬度自行加上即可溺欧,也麻煩把該最小寬度提供給我,我們一起來(lái)完善該份適配柏肪。

以上修改需要在配置文件里修改姐刁,即 screenMatch.properties 文件,該配置文件是執(zhí)行完上面第 3 步后自動(dòng)生成在項(xiàng)目的跟目錄下的烦味。如下圖:


AutoLayout適配

用法

(1) 引入autolayout

```

dependencies {

? ? compile project(':autolayout')

}

```

在你的項(xiàng)目的AndroidManifest中注明你的設(shè)計(jì)稿的尺寸聂使。

```


<

meta-data android:name="design_width" android:value="768"></meta-data>

<meta-data android:name="design_height" android:value="1280"></meta-data>

```

(2)Activity中開(kāi)啟設(shè)配

讓你的Activity去繼承AutoLayoutActivity


今日頭條適配方案(AutoSize)

使用步驟

1、添加依賴(lài)

```

api 'me.jessyan:autosize:1.1.2'

```

2、填寫(xiě)項(xiàng)目設(shè)計(jì)圖尺寸

```

<manifest><application><meta-dataandroid:name="design_width_in_dp"android:value="540"/><meta-dataandroid:name="design_height_in_dp"android:value="960"/></application></manifest>

```

有兩種類(lèi)型的布局單位可以選擇柏靶,一個(gè)是 主單位 (dp弃理、sp),一個(gè)是 副單位 (pt宿礁、in案铺、mm)

主單位: 使用 dp蔬芥、sp 為單位進(jìn)行布局梆靖,侵入性最低,會(huì)影響其他三方庫(kù)頁(yè)面笔诵、三方庫(kù)控件以及系統(tǒng)控件的布局效果返吻,但 AndroidAutoSize 也通過(guò)這個(gè)特性,使用 ExternalAdaptManager 實(shí)現(xiàn)了在不修改三方庫(kù)源碼的情況下適配三方庫(kù)的功能

副單位: 使用 pt乎婿、in测僵、mm 為單位進(jìn)行布局,侵入性高谢翎,對(duì)老項(xiàng)目的支持比較好捍靠,不會(huì)影響其他三方庫(kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件的布局效果森逮,可以徹底的屏蔽修改 density 所造成的所有未知和已知問(wèn)題榨婆,但這樣 AndroidAutoSize 也就無(wú)法對(duì)三方庫(kù)進(jìn)行適配

到這里autosize的框架接入就已經(jīng)完成了,已經(jīng)能夠?qū)崿F(xiàn)autosize的基本功能了


進(jìn)階使用

在 AndroidManifest.xml 中填寫(xiě)的設(shè)計(jì)尺寸褒侧,是整個(gè)項(xiàng)目的全局設(shè)計(jì)圖尺寸但是如果某些 Activity 頁(yè)面由于某些原因良风,這個(gè)頁(yè)面的設(shè)計(jì)圖尺寸和在 AndroidManifest.xml 中填寫(xiě)的設(shè)計(jì)圖尺寸不一樣該怎么辦呢?則可以讓這個(gè)頁(yè)面的 Activity 實(shí)現(xiàn) CustomAdapt 闷供,CustomAdapt 接口的第一個(gè)方法可以修改當(dāng)前頁(yè)面的設(shè)計(jì)尺寸烟央。

```

publicclassCustomAdaptActivityextendsAppCompatActivityimplementsCustomAdapt{/**

? ? * 是否按照寬度進(jìn)行等比例適配 (為了保證在高寬比不同的屏幕上也能正常適配, 所以只能在寬度和高度之中選擇一個(gè)作為基準(zhǔn)進(jìn)行適配)

? ? *

? ? * @return {@code true} 為按照寬度進(jìn)行適配, {@code false} 為按照高度進(jìn)行適配

? ? */@OverridepublicbooleanisBaseOnWidth(){returnfalse;}/**

? ? * 設(shè)計(jì)圖尺寸為 1080px * 1920px, 高換算成 dp 為 960 (1920px / 2 = 960dp)

? ? * <p>

? ? * 返回的設(shè)計(jì)尺寸, 單位 dp

? ? * {@link #getSizeInDp} 須配合 {@link #isBaseOnWidth()} 使用, 規(guī)則如下:

? ? * 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 則應(yīng)該返回設(shè)計(jì)圖的總寬度

? ? * 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 則應(yīng)該返回設(shè)計(jì)圖的總高度

? ? * 如果您不需要自定義設(shè)計(jì)圖上的設(shè)計(jì)尺寸, 想繼續(xù)使用在 AndroidManifest 中填寫(xiě)的設(shè)計(jì)圖尺寸, {@link #getSizeInDp} 則返回 {@code 0}

? ? *

? ? * @return 單位 dp

? ? */@OverridepublicfloatgetSizeInDp(){return667;}}

```

如果你想放棄某個(gè)activity的適配你只需要實(shí)現(xiàn) CancelAdapt 接口即可

```

public class CancelAdaptActivity extends AppCompatActivity implements CancelAdapt{

...

}

```

當(dāng)你想要自定義fragment時(shí)你需要在app初始化時(shí)開(kāi)啟支持

在Applicationl類(lèi)的oncreate方法中添加

```

AutoSizeConfig.getInstance().setCustomFragment(true);

```

萬(wàn)能解決方案

在任何情況下本來(lái)適配正常的布局突然出現(xiàn)適配失效,適配異常等問(wèn)題歪脏,只要重寫(xiě) Activity 的 getResources() 方法即可疑俭,如果是 Dialog、PopupWindow 等控件出現(xiàn)適配失效或適配異常婿失,同樣在每次 show() 之前調(diào)用 AutoSize#autoConvertDensity() 即可怠硼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市移怯,隨后出現(xiàn)的幾起案子香璃,更是在濱河造成了極大的恐慌,老刑警劉巖舟误,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葡秒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)眯牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)蹋岩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人学少,你說(shuō)我怎么就攤上這事剪个。” “怎么了版确?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵扣囊,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我绒疗,道長(zhǎng)侵歇,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任吓蘑,我火速辦了婚禮惕虑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘磨镶。我一直安慰自己溃蔫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布琳猫。 她就那樣靜靜地躺著伟叛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沸移。 梳的紋絲不亂的頭發(fā)上痪伦,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音雹锣,去河邊找鬼网沾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蕊爵,可吹牛的內(nèi)容都是我干的辉哥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼攒射,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼醋旦!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起会放,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饲齐,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后咧最,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體捂人,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡御雕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滥搭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酸纲。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瑟匆,靈堂內(nèi)的尸體忽然破棺而出闽坡,到底是詐尸還是另有隱情,我是刑警寧澤愁溜,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布疾嗅,位于F島的核電站,受9級(jí)特大地震影響祝谚,放射性物質(zhì)發(fā)生泄漏宪迟。R本人自食惡果不足惜酣衷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一交惯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧穿仪,春花似錦席爽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至紫谷,卻和暖如春齐饮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笤昨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工祖驱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞒窒。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓捺僻,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親崇裁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匕坯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • 本文參考自: Google的官方權(quán)威適配文檔 郭霖:Android官方提供的支持不同屏幕大小的全部方法 Storm...
    M悇芐冋憶閱讀 12,815評(píng)論 5 56
  • 目錄介紹 1.屏幕適配定義 2.相關(guān)重要的概念2.1 屏幕尺寸[物理尺寸]2.2 屏幕分辨率[px]2.3 屏幕像...
    楊充211閱讀 1,539評(píng)論 0 1
  • 在我們學(xué)習(xí)如何進(jìn)行屏幕適配之前,我們需要先了解下為什么Android需要進(jìn)行屏幕適配拔稳。 由于Android系統(tǒng)的開(kāi)...
    知青的葉閱讀 1,502評(píng)論 0 2
  • 一, 關(guān)于適配的一些概念性的知識(shí) 1.1. 重要的概念解釋 1.1.1. 屏幕尺寸: 屏幕尺寸指屏幕的對(duì)角線(xiàn)的長(zhǎng)度...
    Simon_Zhang閱讀 1,572評(píng)論 1 3
  • 草書(shū)虛云老和尚山居六首節(jié)錄葛峻,為半年的#可一書(shū)法禪#草書(shū)季劃上了逗號(hào)。書(shū)寫(xiě)無(wú)止境巴比,活到老學(xué)到老术奖。
    學(xué)止閱讀 3,048評(píng)論 0 5