編輯:關於Android編程
1、常用單位及其關系
px:像素
inch:英寸
pt:1/72 英寸
dpi:一英寸長的直線上的像素點的數量,即像素密度。不同的設備,dpi值不同,顯示效果不同,dpi的值跟設備硬件有關。標准值是160dp。
dp(dip):獨立像素密度。即在標准屏幕下,1個像素點的長度,標准屏幕是160dpi,可以理解為1英寸長度上有160個像素。標准屏幕中1dp=1px。
px = dp*(dpi/160);//當dpi=160時,1px=1dp
分辨率:屏幕上長寬方向上像素點的數量,即一個屏幕上像素的數量。
例如:720*1280 = 屏幕x軸上有720個像素,屏幕y軸上有1280個像素
分辨率單位:dpi(點每英寸)、lpi(線每英寸)、ppi(像素每英寸)
屏幕的物理尺寸:屏幕對角線的長度,單位是inch
sp:專用於設定文字大小,受dpi影響和用戶的字體偏好設定影響。
各單位和px的換算關系見TypedValue.applyDimension方法
public static float applyDimension(int unit, float value, DisplayMetrics metrics) { switch (unit) { case COMPLEX_UNIT_PX: return value; case COMPLEX_UNIT_DIP: return value * metrics.density; case COMPLEX_UNIT_SP: return value * metrics.scaledDensity; case COMPLEX_UNIT_PT: return value * metrics.xdpi * (1.0f/72); case COMPLEX_UNIT_IN: return value * metrics.xdpi; case COMPLEX_UNIT_MM: return value * metrics.xdpi * (1.0f/25.4f); } return 0; }
//顯示器 DisplayMetrics d = getResources().getDisplayMetrics();//可以獲得scaledDensity,densityDpi,heightPixels,widthPixels等信息。 Configuration configuration = getResources().getConfiguration();//獲取設備的配置信息 //configuration.screenHeightDp 當前屏幕可用空間的高度,單位是dp //configuration.screenWidthDp 當前屏幕可用空間的寬度,單位是dp //configuration.densityDpi 當前設備的dpi信息
例子:
已知設備1080*1920,使用DisplayMetrics獲取的實際信息是1080*1776,y軸方向上的像素有誤差是因為軟鍵盤,實際屏幕要小。
使用Configuration獲取的設備的dpi=480dpi,根據公式px=dp*(dpi/160)。
現在px=1080,dpi=480,則dp=360.
使用configuration.screenWidthDp得到的數值為360,和上面用公式算出的一致。
但是y軸方向上用公式計算出來的應該是1776/3=592.但是用scrrenHeightDp獲取的只有567。
通過源碼驗證上述是否成立:
applyDimension方法就是通過輸入的任何值轉換成px,也就是說,該方法是任何單位和px的換算關系。
COMPLEX_UNIT_DIP就是dip單位,就是平時說的dp。和px的換算關系是
value* metrics.density;
metrics.density是密度,默認值是
SystemProperties.getInt("qemu.sf.lcd_density",SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT))/ 160
160是中密度屏幕的標准dpi
所以屏幕密度density=設備dpi/160
DENSITY_DEFAULT=160
densityDpi=SystemProperties.getInt("qemu.sf.lcd_density",SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT))/DENSITY_DEFAULT
density=densityDpi/DENSITY_DEFAULT
scaledDensity=density
xdpi=densityDpi
ydpi=densityDpi
但是實際上得到的xdpi!=ydpi的
xdpi:x軸屏幕每英寸的實際物理像素
2、換算方程式
px=dp*(dpi/160) px=sp* metrics.scaledDensity px=sp*(dpi/160) px=pt*xdpi*(1.0f/72) pt*(1/72)=inch px=inch*xdpi px=mm*xdpi*(1.0f*25.4f) mm*(1.0f/25.4f)=inch
易亂點:
分辨率1080*1920單位是像素,有的認為單位是dpi,但是通過源碼驗證,單位就是px
物理尺寸單位是inch
dpi跟設備有關系
只有在dpi=160時,1px=1dp
3、資源查找原則
app運行時,系統會根據屬性選擇適配的資源進行展示。如果有符合的資源則使用,反之,當符合的資源不存在時,系統會去尋找最相近的可用資源來代替。但是,查找的屬性不同,查找的順序會有所有差異。
res文件夾下的資源文件以優先級從高到低排列,命名規則:資源名-屬性1-屬性2-…..
v15修飾的資源僅用於4.0及以上的設備
w640dp修飾的適配640dp寬度的設備
h720dp修飾的資源適配720dp高度的設備
屏幕密度屬性ldpi、mdpi、hdpi、xhdpi、xxhdpi、nodpi、tvdpi
ldpi=120
mdpi=160
hdpi=240
xhdpi=320
xxhdpi=480
xxxhdpi=640
其中nodpi用於開發者不希望系統對圖片進行縮放的情況
tvdpi介於hdpi和mdpi之間。tvdpi一般在213左右,多用於android系統的只能電視,大部分app很少用到
對dpi屬性來說,查找的順序為,高dpi的資源優先。例如,沒能找到hdpi的圖片資源,則系統的搜索順序是
drawable-xhdpi->drawable-xxhdpi->drawable-mdip->drawable->drawable->drawable-ldpi。
這裡drawable被認為比drawable-ldpi更接近hdpi。
有時候,我們的圖片資源不一定是從drawable文件夾中讀取的,還有可能是從sd卡上讀取的,或者從網絡上下載的。這個時候,我們需要注意,默認情況下,通過BitmapFactory.decodeFile()函數生成的圖片被認為是MDPI的,如果想讓圖片也獲得與drawable文件夾相似的縮放能力,則需要通過BitmapFactory.Option.inDensity屬性設置(例如如果圖片是為hdpi准備的,則設置為240)。
對於screan size,查找的順序則是小尺寸優先,大尺寸放棄。例如,在Galaxy note 2上執行apk時,如果未能找到layout-large資源,則查找順序為:layout-normal->layout->layout-small,不會查找layout-xlarge。
4、屏幕適配方案一
步驟:
1)假設設計圖的基准是720*1280,那麼在設計圖中1px對於1920*1080分辨率的手機應該是1.5px
在布局文件中就可以直接使用像素標識了,其實本質上是百分比
布局文件中的使用,比如說現在做一個670*80px的按鈕,在density=1的時候,1dp=1px,在density=2.0的手機,1px=2.0dp,在density=1.5的手機中1px=1.5dp
如果使用dp設置這個button的大小,以2.0為基准,設置大小335*40dp,
在density=1.5的手機上,實際占的大小是502.5*60px。如果手機的分辨率是480*800px的就會出現button顯示不全的情況。
但是,使用上面指定分辨率屬性資源的,根據不同的手機分辨率應用自動尋找對應的資源文件。dimen_670_dip*dimen_80_dip在分辨率720*1280手機中是670*80px
在1080*1920分辨率的手機中是1005*120px。不需要計算就可以得到相應的尺寸。(不需要人為去計算,根據資源查找原則,系統會自動選擇最適合屏幕的資源)
因為大小按照不同的手機不同的分辨率進行了適配,但是字體也要進行適配。不然大小變小了,字體沒有適配就會出現太小或太大的問題。
pt和sp的換算關系還跟用戶的設置有關系,所以最好的方法就是,字體大小也使用px單位的換算。
5、屏幕適配方案二-------谷歌百分比布局庫
android-support-percent.jar
方案一的適配已經運用在多款互聯網應用,但是方案一的適配有一個缺點,就是會增加apk的大小。
使用谷歌的百分比布局庫就可以解決這個問題
百分比布局庫就是講RelativeLayout換成PercentRelativeLayout,
將FrameLayout換成PercentFrameLayout
支持寬高設置和margin設置
Eclipse中直接將jar復制進libs文件夾,並依賴庫percent
F:\Android\SDK\extras\android\support\percent
sdk路徑/extras/android/support/percent
AndroidStudio在build.gradle中添加compile 'com.android.support:percent:22.2.0'
使用示例
6、常用方法
/** * 根據手機的分辨率從 dp 的單位 轉成為 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根據手機的分辨率從 px(像素) 的單位 轉成為 dp */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } public static int getScreenWidth(Activity activity){ DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); int screenWidth = dm.widthPixels; return screenWidth; } public static int getScreenHeigth(Activity activity){ DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); int screenHeigh = dm.heightPixels; return screenHeigh; } public static int measureHeight(View view){ int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); view.measure(w, h); int height =view.getMeasuredHeight(); return height; } public static int measureWidth(View view){ int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); view.measure(w, h); int width =view.getMeasuredWidth(); return width; }
本文來自http://blog.csdn.net/yihongyuelan 轉載請務必注明出處 本文代碼以MTK平台Android 4.4為分析對象,與Google原
搭建react-native for android的windows開發環境移動應用的開發分為ios和android兩個平台,開發一款應用就需要做兩次不同的開發。而rea
GitHub:https://github.com/baiyuliang/QRobot小Q聊天機器人1.2版本中加入語音識別及語音合成功能,語音識別即將語音轉化為文字輸出
這篇文章將給大家介紹android圖片處理的高效做法,大家有需求的時候可以參考一下。首先我要說明一下本實例中實現的效果(我還不會制作gif圖,如果誰會的話,希望可以教一下