dp


? ? ? ?回頭算算去扣,從正式開始做Android,剛好一年時間樊破,在這里所謂的互聯(lián)網(wǎng)寒冬毅然決然的入了Android的坑厅篓。不過話又說回來了秀存,我一直堅信技術(shù)的積累與大環(huán)境無關(guān),所以關(guān)鍵還是在于提升自己羽氮。之前在初入Android坑的工作中或链,都是使用印象筆記作為知識的積累,但是久而久之變得有點雜亂档押。因此最近年后一直考慮開始寫文章澳盐,把一些用到的知識點整理出來。最后選擇了簡書作為我的筆記本令宿。知識是需要沉淀的叼耙,總結(jié)出來的東西肯定會有不一樣的領(lǐng)悟。如果剛好這些東西能幫助到其他人粒没,那就更好了筛婉。

? ? ? ?好了,廢話這么多癞松,進入今天的正題吧爽撒。相信沒有做Android開發(fā)的朋友也一定知道一個事實:由于Android開源,因此采用Android系統(tǒng)的廠商非常之多响蓉,設(shè)備也非常多硕勿,而且各種尺寸和各種分辨率的組合也是多如牛毛。下面這張圖是從友盟發(fā)布的報告上截取的枫甲。因此適配就成Android開發(fā)中的必不可少的工作源武。下面我將從幾部分來說一說Android中的單位dp。

圖-1

1想幻、基本概念

? ? ? ?首先要說的就是px粱栖。px是屏幕中可以顯示的最小元素單元。我們的手機(或平板)可以顯示的東西都是由一個個像素點組成的脏毯。在PC上查排,我們可以通過px這個單位就能把程序打扮的很漂亮,但是手機上卻不行抄沮。我舉個例子跋核,比如我們現(xiàn)在要在界面上畫一個button,設(shè)置按鈕寬度為200px叛买,我分別在1920*1080和800*480的兩臺設(shè)備上預(yù)覽的效果如下:


圖-2(1920*1080)
圖-3(800*480)

結(jié)果是一目了然砂代,在1920*1080的設(shè)備中,300px的像素大于只占屏幕寬度的不到三分之一率挣,而在800*480的設(shè)備中刻伊,卻占了一半還要多。因此,px作為單位肯定不行捶箱。google當(dāng)然也意識到了這個問題智什,因此引入了dp和sp兩個單位作為控件單位和字體單位。

我們先了解幾個相關(guān)的概念丁屎。

dp:也稱為dip荠锭,device independent pixels,設(shè)備獨立像素晨川。

dpi:全稱是 Dots Per Inch,每英寸所包含的像素數(shù)证九。

density:像素密度。計算公式為dpi/160共虑。

google官方規(guī)定愧怜,以dpi為160作為基準,即在一臺dpi為160的設(shè)備上妈拌,1px=1dp拥坛,此時該設(shè)備的density也為1。根據(jù)這個規(guī)定尘分,你可以對其他設(shè)備進行計算猜惋。例如一臺手機的屏幕寬是2英寸,長是3英寸音诫,分辨率為640*960惨奕。那么它的dpi值等于640/2(或者960/3)=320,density等于320/160=2雪位,1dp=1px*2竭钝。

這樣你應(yīng)該對dp這個單位有了一定的了解吧,我們最終看dp是實現(xiàn)了什么樣的效果雹洗。當(dāng)我把一個控件的寬度設(shè)置為1dp是香罐,在google定義的基準設(shè)備上,它所表示的真實長度=1/160英寸时肿。在上面定義的640*960的設(shè)備上庇茫。1dp=2px/320英寸。結(jié)果是一樣的螃成,都是1/160英寸旦签。也就是在不同的設(shè)備上所表現(xiàn)出的物理長度是一樣的。也就初步實現(xiàn)了適配寸宏。

但是實際情況可能沒有這么理想宁炫,例如我的手機魅藍note2,1920*1080,16:9氮凝,5.5英寸羔巢,通過代碼:getResources().getDisplayMetrics().densityDpi;得出的dpi值為480。通過手動計算,勾股定理得:寬為2.7英寸竿秆,高為4.8英寸启摄,dpi值等于:1080/2.7=400dpi,1920/4.8=400dpi幽钢。咦歉备?怎么兩個值不一樣,事實是這樣的:編譯ROM的時候會指定dpi,而且只能指定如下幾個值搅吁。

ldpi: 120dpi (mdpi x 0.75)

mdpi: 160dpi? (android 基準 dpi, 1dp=1px)

hdpi: 240dpi (mdpi x 1.5)

xhdpi: 320dpi(mdpi x 2)

xxhdpi: 480dpi(mdpi x 3)

xxxhdpi: 640dpi(mdpi x 4)

到目前這個階段威创,ldpi的設(shè)備已經(jīng)基本很少了,所以不做考慮谎懦。手機廠商應(yīng)該盡量讓手機的實際像素密度與ROM指定的值接近肚豺,請注意,是接近界拦,所以才會出現(xiàn)了上面的偏差吸申。假如屏幕 A 實際是 440dpi 的,ROM 被指定為 480 dpi享甸,那么屏幕顯示的實際上是 480/440=1.09 倍的真實大小截碴。

好了,上面費這么多話蛉威,其實只想說一絕話:

1dp約等于1/160英寸H盏ぁ!

2蚯嫌、Android屏幕適配方案

1哲虾、布局適配

做法:盡量使用相對布局

? ? ? ?目前為止,我們在進行布局界面的時候通常使用的布局包括: RelativeLayout择示、LinearLayout束凑、FrameLayout。推薦優(yōu)先使用RelativeLayout栅盲,RelativeLayout的特點是布局下的子控件之間使用相對位置的方式排列汪诉。即使屏幕的大小改變,視圖之前的相對位置都不會變化谈秫,與屏幕大小無關(guān)扒寄,靈活性很強。而LinearLayout布局無法控制子視圖之間的關(guān)系拟烫,只能一個挨一個的按照垂直或水平排列该编。而FrameLayout是把所有的元素都放在屏幕的左上方。如果要進行元素排布的話构灸,只能通過固定的dp值上渴。因此岸梨,對于屏幕適配而言,使用RelativeLayout是比較好的方案稠氮。

2曹阔、布局組件適配

? ? ? ?布局組件適配比較容易理解。即我們最常用的match_parent和wrap_content隔披。設(shè)置控件的寬和高時赃份,當(dāng)我們通過這兩個屬性值就可以設(shè)置控件的寬高為與父控件的寬高一致、適應(yīng)該控件的寬高奢米,而不需要指定固定的dp值抓韩。因此,也是屏幕適配優(yōu)先使用的控件屬性鬓长。

3谒拴、布局限定符適配

? 使用尺寸限定符

? ? ? ?Android 3.2之前通過small、normal涉波、large英上、xLarge分別標記小尺寸屏幕、正常尺寸屏幕啤覆、大尺寸屏幕苍日、超大尺寸屏幕。同一界面在不同的布局文件路徑下創(chuàng)建布局文件:res/layout/my_layout.xml窗声;

res/layout-large/my_layout.xml相恃;

res/layout-xlarge/my_layout.xml腋妙;

但是該種方法區(qū)分屏幕的邊界比較模糊碗啄,因此從Android 3.2之后就被棄用乾颁。鑒于目前4.0以下的系統(tǒng)基本可以忽略不計狗准,則此種方法目前來說基本是廢棄狀態(tài)。

??使用最小寬度限定符

? ? ? ?上面說到尺寸限定符已經(jīng)被廢棄掉了简烤,google的替代方案就是smallestWidth,設(shè)備的 smallestWidth 是屏幕可用高度和寬度的最小尺寸,smallestWidth 是設(shè)備的固定屏幕尺寸特性炮温;設(shè)備的 smallestWidth 不會隨屏幕方向的變化而改變。如果設(shè)備的屏幕上有一些永久性 UI 元素占據(jù)沿 smallestWidth 軸的空間牵舵,則系統(tǒng)會聲明 smallestWidth 小于實際屏幕尺寸柒啤。關(guān)鍵字:sw<N>dp。如:sw600dp畸颅、sw720dp担巩。同一界面在不同的布局文件路徑下創(chuàng)建布局文件:

res/layout/main_activity.xml

res/layout-sw600dp/main_activity.xml

??使用屏幕方向限定符

? ? ? ?如果我們要求給橫屏、豎屏顯示的布局不一樣没炒。就可以使用屏幕方向限定符來實現(xiàn)涛癌。在布局文件夾中增加關(guān)鍵字land、port實現(xiàn)。例如要在平板上實現(xiàn)橫豎屏顯示不用的布局拳话。同一界面在不同的布局文件路徑下創(chuàng)建布局文件:

res/values-sw600dp-land/layouts.xml:橫屏

res/values-sw600dp-port/layouts.xml:豎屏

3先匪、圖片資源適配

圖片資源適配優(yōu)先使用Android特用的九圖格式。

使用場景:當(dāng)我們需要使圖片在拉伸后還能保持一定的顯示效果弃衍,比如呀非,不能使圖片中的重要像素拉伸,不能使內(nèi)容區(qū)域受到拉伸的影響镜盯,我們就可以使用.9.png圖來實現(xiàn)岸裙。

使用方法說明:1、在九圖工具中速缆,選擇圖片的左邊和上邊降允,點選一個或多個像素點,即可把這些垂直水平方向選中的像素點進行拉伸處理艺糜。2拟糕、右邊和下邊是選擇內(nèi)容區(qū)域,在右邊和下邊畫上直線倦踢,交叉的區(qū)域就是內(nèi)容區(qū)域送滞,即文本顯示區(qū)域。


9圖可以根據(jù)屏幕的尺寸進行自由適配辱挥,因此是控件背景圖片的第一選擇犁嗅。但是并不是所有需要圖片的地方都要用9圖。其他需要圖片的地方晤碘,我們要根據(jù)前面說到的mdpi褂微、hdpi、xhdpi园爷、xxhdpi宠蚂、xxxhdpi幾種不同的設(shè)備進行切圖,你如果觀察過新建Android項目的app的icon的尺寸的話童社,你會發(fā)現(xiàn)在mipmap相關(guān)的幾個文件夾中求厕,它的尺寸分別為:48*48、72*72扰楼、96*96呀癣、144*144、192*192弦赖,它們轉(zhuǎn)換后都為48dp*48dp项栏,也就是說它們在設(shè)備上表現(xiàn)出的物理尺寸是基本一致的,也就實現(xiàn)了圖片的適配蹬竖。但是實際情況不可能這么完美沼沈,公司UI一般不會花這么大精力去做這么多圖對我們的設(shè)備進行適配流酬,另外也要考慮這樣apk的大小會增大不少。

所以一般是給出一種分辨率下的切圖列另,Android系統(tǒng)會自動根據(jù)圖片所放的文件夾和設(shè)備的密度進行相應(yīng)的縮放顯示康吵。這樣的方式圖片在app上也會有不錯的呈現(xiàn)效果。但是這個地方有不少細節(jié)需要注意访递,下一篇我們會在去講解晦嵌。

4、用戶界面流程適配

? ? ? ?前面有說到根據(jù)最小寬度限定符創(chuàng)建不同的布局文件拷姿。但是我們怎么在具體Activity中判斷究竟當(dāng)前設(shè)備是加載了哪個布局惭载,那些事件可以得到響應(yīng)。

1响巢、確定當(dāng)前布局

? 通過判斷某個控件是否為null描滔。這個控件如果只在一種布局下存在,那個可以使用此方法踪古。

? 通過判定某個控件的事件含长。如這個控件只在一種布局下才生效。

2伏穆、根據(jù)當(dāng)前的布局做出響應(yīng)

? ? ? ?有些操作可能會因當(dāng)前的具體布局而產(chǎn)生不同的結(jié)果拘泞。例如,在新聞閱讀器示例中枕扫,如果用戶界面處于雙面板模式下陪腌,那么點擊標題列表中的標題就會在右側(cè)面板中打開相應(yīng)報道;但如果用戶界面處于單面板模式下烟瞧,那么上述操作就會啟動一個獨立活動诗鸭。

3、重復(fù)使用其他活動中的片段

? ? ? ?多屏幕設(shè)計中的重復(fù)模式是指参滴,對于某些屏幕配置强岸,已實施界面的一部分會用作面板;但對于其他配置砾赔,這部分就會以獨立活動的形式存在蝌箍。例如,在新聞閱讀器示例中过蹂,對于較大的屏幕十绑,新聞報道文本會顯示在右側(cè)面板中聚至;但對于較小的屏幕酷勺,這些文本就會以獨立活動的形式存在。

在類似情況下扳躬,通炒嗨撸可以在多個活動中重復(fù)使用相同的 Fragment 子類以避免代碼重復(fù)甚亭。例如,在雙面板布局中使用了 ArticleFragment:

圖-4

而在小屏幕上可以直接:

ArticleFragment frag =newArticleFragment();

getSupportFragmentManager().beginTransaction().add(android.R.id.content,?frag).commit();

這種方式與在 XML 布局中聲明片段的效果是一樣的击胜,但在這種情況下卻沒必要使用 XML 布局亏狰,因為此Fragment是此活動中的唯一組件。

另外偶摔,在Fragment中注意暇唾,不要針對具體Activity創(chuàng)建強耦合。要做到這一點辰斋,通巢咧荩可以定義一個接口,該接口概括了Fragment與其主Activity交互所需的全部方式宫仗,然后讓Activity更新界面够挂。這部分的內(nèi)容具體可參考凱子哥的一篇文章,鏈接在后面藕夫。


好了孽糖。關(guān)于Android中dp的認識我已經(jīng)把我所有的理解都放在這里了。如有錯誤請指正毅贮,共同進步办悟。



參考資料:

http://blog.csdn.net/zhaokaiqiang1992/article/details/45419023

http://www.reibang.com/p/ec5a1a30694b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市滩褥,隨后出現(xiàn)的幾起案子誉尖,更是在濱河造成了極大的恐慌,老刑警劉巖铸题,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铡恕,死亡現(xiàn)場離奇詭異,居然都是意外死亡丢间,警方通過查閱死者的電腦和手機探熔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烘挫,“玉大人诀艰,你說我怎么就攤上這事∫” “怎么了其垄?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卤橄。 經(jīng)常有香客問我绿满,道長,這世上最難降的妖魔是什么窟扑? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任喇颁,我火速辦了婚禮漏健,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘橘霎。我一直安慰自己蔫浆,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布姐叁。 她就那樣靜靜地躺著瓦盛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪外潜。 梳的紋絲不亂的頭發(fā)上谭溉,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音橡卤,去河邊找鬼扮念。 笑死,一個胖子當(dāng)著我的面吹牛碧库,可吹牛的內(nèi)容都是我干的柜与。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼嵌灰,長吁一口氣:“原來是場噩夢啊……” “哼弄匕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沽瞭,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤迁匠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驹溃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體城丧,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年豌鹤,在試婚紗的時候發(fā)現(xiàn)自己被綠了亡哄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡布疙,死狀恐怖蚊惯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灵临,我是刑警寧澤截型,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站儒溉,受9級特大地震影響宦焦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一赶诊、第九天 我趴在偏房一處隱蔽的房頂上張望笼平。 院中可真熱鬧园骆,春花似錦舔痪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晌涕,卻和暖如春滋捶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背余黎。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工重窟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惧财。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓巡扇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親垮衷。 傳聞我的和親對象是個殘疾皇子厅翔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

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