日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

[转]Android中dp,px,sp概念梳理以及如何做到屏幕适配

發(fā)布時間:2024/4/15 Android 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]Android中dp,px,sp概念梳理以及如何做到屏幕适配 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://blog.csdn.net/jiangwei0910410003/article/details/40509571

?

今天又開始我的App開發(fā),因為之前一直做的是SDK,所以涉及到界面UI很少,剛開始做Android應(yīng)用的時候,沒有對dp,px,sp等概念有一個深入的了解,只知道他們之間的轉(zhuǎn)化,還有寫個轉(zhuǎn)換工具類等。做Android已經(jīng)有一年多了,現(xiàn)在再次開始App開發(fā),決定沒遇到一個概念,必須得弄透徹。好吧,下面進入主題吧:

?

首先來看一下他們的基本概念:

px ? :是屏幕的像素點
dp ? :一個基于density的抽象單位,如果一個160dpi的屏幕,1dp=1px
dip ?:等同于dp
sp ? :同dp相似,但還會根據(jù)用戶的字體大小偏好來縮放(建議使用sp作為文本的單位,其它用dip)

?

通過上面的知識我們可以看到這里只要弄懂px和dp之間的關(guān)系就可以了。那么下面重點來看一下他們兩之間的關(guān)系:

針對dip和px 的關(guān)系,做以下概述:

1). px (pixels)像素 :

一個像素通常被視為圖像的最小的完整采樣,這個用的比較多,特別是web開發(fā),頁面基本都是使用像素作為單位的.

2). dip或dp (device independent pixels):

設(shè)備獨立像素 — 這個和設(shè)備硬件有關(guān),一般我們?yōu)榱酥С质謾C上多種分辨率,如WVGA、HVGA

和QVGA,都會使用dip作為長度的單位

下面來看一下手機屏幕類型和密度以及分辨率的對應(yīng)關(guān)系

QVGA屏density=120 ? ? ? ? QVGA(240*320)
HVGA屏density=160 ? ? ? ? HVGA(320*480)
WVGA屏density=240 ? ? ? ?WVGA(480*800)
WQVGA屏density=120 ? ? ?WQVGA(240*400)

?

注:density值表示每英寸有多少個顯示點,與分辨率是兩個概念。

?

不同density下屏幕分辨率信息是不同的,以480dip*800dip的 WVGA(density=240)為例

1、當(dāng)density=120時?

轉(zhuǎn)化:轉(zhuǎn)化系數(shù)=120/240

屏幕實際分辨率為240px*400px (兩個點對應(yīng)一個分辨率)

狀態(tài)欄和標(biāo)題欄高各19px或者25dip

橫屏是屏幕寬度400px 或者800dip,工作區(qū)域高度211px或者480dip

豎屏?xí)r屏幕寬度240px或者480dip,工作區(qū)域高度381px或者775dip

2、當(dāng)density=160時?

轉(zhuǎn)化:轉(zhuǎn)化系數(shù)=160/240

屏幕實際分辨率為320px*533px (3個點對應(yīng)兩個分辨率)

狀態(tài)欄和標(biāo)題欄高個25px或者25dip

橫屏是屏幕寬度533px 或者800dip,工作區(qū)域高度295px或者480dip

豎屏?xí)r屏幕寬度320px或者480dip,工作區(qū)域高度508px或者775dip

3、當(dāng)density=240時?

轉(zhuǎn)化:轉(zhuǎn)化系數(shù)=240/240

屏幕實際分辨率為480px*800px (一個點對于一個分辨率)

狀態(tài)欄和標(biāo)題欄高個38px或者25dip

橫屏是屏幕寬度800px 或者800dip,工作區(qū)域高度442px或者480dip

豎屏?xí)r屏幕寬度480px或者480dip,工作區(qū)域高度762px或者775dip

我們一般在項目中會定義多個適配資源文件夾(values-XXX,drawable-XXX等)

drawable-ldpi: ? ? 屏幕密度為120的手機設(shè)備

drawable-mdpi: ? 屏幕密度為160的手機設(shè)備(此為baseline,其他均以此為基準(zhǔn),在此設(shè)備上,1dp = 1px)

drawable-hdpi: ? ?屏幕密度為240的手機設(shè)備

drawable-xhdpi: ?屏幕密度為320的手機設(shè)備

drawable-xxhdpi:屏幕密度為480的手機設(shè)備

(values也是一樣,當(dāng)然還有一點要注意:values和values-hdpi效果是一樣的,drawable和drawable-hdpi效果也是一樣的,所以一般我們都會在這兩個文件夾中存放的值是一樣的,如果兩個都有的話,適配更好)


apk的資源包中

當(dāng)屏幕density=240時,使用hdpi 標(biāo)簽的資源

當(dāng)屏幕density=160時,使用mdpi標(biāo)簽的資源

當(dāng)屏幕density=120時,使用ldpi標(biāo)簽的資源

當(dāng)屏幕density=320時,使用xhdpi標(biāo)簽的資源

當(dāng)屏幕density=480時,使用xxhdpi標(biāo)簽的資源

不加任何標(biāo)簽的資源是各種分辨率情況下共用的

所以布局時盡量使用單位dip,少使用px

dp與px換算公式:
pixs =dips * (densityDpi/160).?
dips=(pixs*160)/densityDpi

但是我們在代碼里面進行轉(zhuǎn)化的時候還需要有一個偏移值:0.5f

?

[java]?view plaincopy
  • private?static?final?float?scale?=?mContext.getResources().getDisplayMetrics().density;??
  • ??
  • private?static?final?float?scaledDensity?=?mContext.mContext.getResources().getDisplayMetrics().scaledDensity;??
  • ??
  • /**?
  • ?*?dp轉(zhuǎn)成px?
  • ?*?@param?dipValue?
  • ?*?@return?
  • ?*/??
  • public?static?int?dip2px(float?dipValue)?{??
  • ????return?(int)?(dipValue?*?scale?+?0.5f);??
  • }??
  • ??
  • /**?
  • ?*?px轉(zhuǎn)成dp?
  • ?*?@param?pxValue?
  • ?*?@return?
  • ?*/??
  • public?static?int?px2dip(float?pxValue)?{??
  • ????return?(int)?(pxValue?/?scale?+?0.5f);??
  • }??
  • ??
  • /**?
  • ?*?sp轉(zhuǎn)成px?
  • ?*?@param?spValue?
  • ?*?@param?type?
  • ?*?@return?
  • ?*/??
  • public?static?float?sp2px(float?spValue,?int?type)?{??
  • ????switch?(type)?{??
  • ????case?CHINESE:??
  • ????????return?spValue?*?scaledDensity;??
  • ????case?NUMBER_OR_CHARACTER:??
  • ????????return?spValue?*?scaledDensity?*?10.0f?/?18.0f;??
  • ????default:??
  • ????????return?spValue?*?scaledDensity;??
  • ????}??
  • }??
  • ?

    我們看到,這里的scale是在這個類DisplayMetrics中定義的全局變量,其實這個值就是當(dāng)前手機的density/160,scaleDensity是用來px和sp之間的轉(zhuǎn)化和scale差不多。還有一點就是這里轉(zhuǎn)化都會有一個偏移值處理

    dp這個單位可能對web開發(fā)的人比較陌生,因為一般都是使用px(像素)
    但是,現(xiàn)在在開始android應(yīng)用和游戲后,基本上都轉(zhuǎn)換成用dp作用為單位了,因為可以支持多種分辨率的手機.

    ?

    上面看到了px和dp之間的關(guān)系以及轉(zhuǎn)化,下面在來看一下使用場景吧,就是為什么我們會使用到他們之間的轉(zhuǎn)化,我們在xml中一般定義大小都是使用dp為單位的,但是有時候我們需要在代碼里面設(shè)置一些間距和位置:

    下面的代碼

    [java]?view plaincopy
  • android.view.ViewGroup.LayoutParams.height??
  • android.view.ViewGroup.LayoutParams.width??

  • 上面這兩個屬性的單位為像素,但是為了兼容多種分辨率的手機,我們需要最好使用dip,時候我們可以調(diào)用以下的代碼進行轉(zhuǎn)換.

    [java]?view plaincopy
  • int?heightPx=?DisplayUtil.dip2px(this,?33);??
  • mTabHost.getTabWidget().getChildAt(i).getLayoutParams().height?=?heightPx;??
  • ?

    當(dāng)然我們有時候也會在代碼中獲取values文件夾中的demen.xml文件中的值,代碼如下:

    ?

    [java]?view plaincopy
  • float?height?=?this.getResources().getDimension(R.dimen.height);??
  • txt.height?=?px2dip((int)height);//將height轉(zhuǎn)化成px??
  • ?

    不知道他獲取的就是dimens.xml文件中定義的dp值,所以這里還手動的進行了轉(zhuǎn)化操作,但是發(fā)現(xiàn)顯示的效果和我們預(yù)期不一樣,然后就把值打印了一下看,盡然是兩倍,就是通過getDimension方法獲取到的值是dimen.xml文件中定義的值的兩倍,這不科學(xué)呀,然后就search一下了,發(fā)現(xiàn)有三個類似的方法,

    getDimension

    getDimensionPixelOffset

    getDimensionPixelSize

    他們的功能都是不一樣的:

    通過一個例子來看看他們的區(qū)別:

    dimen.xml:

    ?

    [html]?view plaincopy
  • <dimen?name="activity_vertical_margin1">16dp</dimen>????
  • <dimen?name="activity_vertical_margin2">16px</dimen>????
  • <dimen?name="activity_vertical_margin3">16sp</dimen>???
  • ?

    代碼:

    ?

    [java]?view plaincopy
  • float?a1=getResources().getDimension(R.dimen.activity_vertical_margin1);????
  • int?a2=getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin1);????
  • int?a3=getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin1);????
  • ??
  • float?b1=getResources().getDimension(R.dimen.activity_vertical_margin2);????
  • int?b2=getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin2);????
  • int?b3=getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin3);????
  • ??
  • float?c1=getResources().getDimension(R.dimen.activity_vertical_margin3);????
  • int?c2=getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin3);????
  • int?c3=getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin3);????
  • ??
  • Log.i("test",?"getDimension=?"+a1+",?getDimensionPixelOffset="+a2+",getDimensionPixelSize="+a3);????
  • Log.i("test",?"getDimension=?"+b1+",?getDimensionPixelOffset="+b2+",getDimensionPixelSize="+b3);????
  • Log.i("test",?"getDimension=?"+c1+",?getDimensionPixelOffset="+c2+",getDimensionPixelSize="+c3);??????
  • ?

    ?

    對于設(shè)備1(1280*720,160dpi,density=1.0):

    打印結(jié)果:

    對于設(shè)備2(480*800,240dpi,density=1.5):

    打印結(jié)果:

    ?

    可見getDimension和getDimensionPixelOffset的功能差不多,都是獲取某個dimen的值,如果是dp或sp的單位,將其乘以density,如果是px,則不乘;兩個函數(shù)的區(qū)別是一個返回float,一個返回int.
    getDimensionPixelSize則不管寫的是dp還是sp還是px,都會乘以denstiy.

    所以我們在使用getDimension方法獲取到的值的時候就不需要進行轉(zhuǎn)化了~~

    ?

    下面是我在工作中進行屏幕適配的小工具:http://download.csdn.net/detail/jiangwei0910410003/8144585

    是一個小Demo,運行之后,就可以得到這個設(shè)備獲取資源的文件夾了,然后我們就可以在指定的文件夾中定義它的尺寸即可。

    ?

    總結(jié):dp和px的相關(guān)知識就介紹到這里了,這個只是很容易混淆的,而且在面試和筆試的時候都會遇到,所以這些概念還是弄清楚比較好啦~~

    (PS:其實寫完了,我還是不太記得住~~)

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/exmyth/p/4490821.html

    總結(jié)

    以上是生活随笔為你收集整理的[转]Android中dp,px,sp概念梳理以及如何做到屏幕适配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。