屏幕像素參數相關信息表格
屏幕級別 像素密度 每英寸像素數 一般分辨率 分辨率別稱 默認圖標大小
xxhdpi 3 480 1080*1920 1080P 144*144 重點關注
xhdpi 2 320 720*1280 720P 96*96 適配基準
hdpi 1.5 240 480*800 WVGA 72*72
mdpi 1.0 160 320*480 HVGA 48*48 基準
ldpi 0.75 120 240*320 QVGA 36*36
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 5);//440.58
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 5.5);//400.53
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 6.0);//367.15
主流Android手機分辨率
屏幕級別 倍數/比例 像素密度範圍 主流分辨率/寬高比 分辨率別稱 標準圖標大小
xxxhdpi 4 480-640 2560*1440/16:9 2K 192*192
3840*2160/16:9 4K
xxhdpi 3 320-480 1920*1080/16:9 1080P 144*144
xhdpi 2 240-320 1280*720/16:9 720P 96*96
960*540 QHD
hdpi 1.5 160-240 800*480/5:3 WVGA 72*72
854*480/16:9 FWVGA
640*480/4:3 VGA
800*600/4:3 SVGA
mdpi 1.0 120-160 320*480 HVGA 48*48
ldpi 0.75 120 240*320 QVGA 36*36
iPhone系列手機的分辨率
iPhone 3G/3GS 480 x 320
iPhone 4/4S 960 x 640
iPhone 5/5s/5c 1136 x 640
iPhone 6/6s/7 1334*750
iPhone 6p/6sp/7p 1920*1080
名詞解釋
名詞解釋
- Px(像素Pixel)
- px即像素,一個像素則代表在屏幕上的一個點,一個顯示單位。
- 不一樣設備上顯示時像素數不會變,好比指定控件的長度是100px,那無論分辨率是多少控件長度都是100px。也正是由於如此才產生了屏幕適配問題。
- Screen Size(屏幕的尺寸)
通常所說的手機屏幕大小如5.0英寸,都是指的手機屏幕對角線的長度,而不是手機面積。
- Resolution(屏幕的分辨率)
- 在屏幕上顯示的物理像素總和,單位是px,1px=1個像素點。
- 通常以縱向像素*橫向像素表示,好比分辨率是1280*720,則指設備垂直方向有1280個像素點,水平方向有720個像素點。
- 須要注意的是:分辨率並不意味着具體的屏幕高寬比,好比分辨率爲1280*720的手機屏幕寬高比不必定是1280*720(16:9)。可是爲了顯示效果和諧,二者通常都是一致的(或者有一丟丟的差距)。
- Dpi(像素密度dots per inch)
- 即「dot per inch」的縮寫,指每英寸中的像素數。
- 屏幕像素密度與屏幕尺寸和屏幕分辨率有關,在單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大。
- DisplayMetrics類中屬性density的值即爲此值,可用於px與dip的互相轉換
- dp是一個與密度無關的像素,在不一樣的像素密度的設備上會自動適配,在邏輯尺寸上,與一個位於像素密度爲 160DPI 的屏幕上的像素是一致的,在運行的時候,平臺會以目標屏幕的密度做爲基準,處理全部須要的DIP縮放操做。假定設備分辨率爲320*240,屏幕長2英寸寬1.5英寸,dpi=320/2=240/1.5=160,此160dpi表示手機水平或垂直方向上每英寸距離有160個像素點。
- Dip(設備獨立像素Device-independent pixel)
- dp和dip是一個意思,翻譯爲設備獨立像素,或是密度無關像素
- 在Android中,規定以160dpi爲基準,此時1dip=1px;若是像素密度是320dpi,則1dip=2px
- 要把DIP像素轉換爲屏幕像素,能夠用這樣一個簡單的公式: pixels = dips * (density / 160)。
- Sp(放大像素ScaledPixels)
主要用於字體顯示(best for textsize)。根據 google 的建議,TextView 的字號最好使用 sp 作單位,並且查看TextView的源碼可知 Android 默認使用 sp 做爲字號單位。
屏幕適配方法
一、使用不一樣套圖適配
使用套圖適配目前來講是針對
圖片適配的最好適配方法,能夠
防止圖片的失真以及變形。
但針對不一樣手機進行不一樣的套圖適配,會對UI人員施加過大的工做壓力以及對咱們app自己也會形成冗餘的影響。
二、9path適配
9path圖片做爲特殊的png圖片,能夠在特定的狀況下對不一樣機型進行適配,而達到圖片不失真的狀況。
三、佈局適配
使用權重適配。
在格局比較明朗的頁面中,若是咱們能少用具體大小dp值,多用權重,能夠在不一樣的分辨率下都能作到完美適配。
四、使用dimens適配
根據不一樣values下的dimens進行適配,android項目會自動找尋相適應的dimens,咱們能夠在多種不一樣的values下創建dimens文件。
在使用dimens的時候,咱們能夠在dimens文件中,用px爲單位,這樣就能達到完美適配。
五、代碼適配
咱們也能夠在java文件中,使用java代碼
並結合dimens進行適配,相比較xml的話,此種適配方法更迅捷。
Activity
public class MainActivity extends Activity {
private TextView tv_info;
public static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv_info = new TextView(this);
setContentView(tv_info);
tv_info.setText("" + DensityUtils.getStatusBarHeight(this));//狀態欄高度。奇酷72。華爲75
tv_info.append("\n" + DensityUtils.getDisplayMetrics(this));//像素密度。奇酷2.875。華爲3.0
tv_info.append("\n" + DensityUtils.dp2px(this, 10.3f));
tv_info.append("\n" + DensityUtils.px2dp(this, 10.3f));
tv_info.append("\n" + DensityUtils.sp2px(this, 10.3f));
tv_info.append("\n" + DensityUtils.px2sp(this, 10.3f));
tv_info.append("\n" + DensityUtils.getScreenWidth(this) + "-" + DensityUtils.getScreenWidth2(this));
tv_info.append("\n屏幕高度:" + DensityUtils.getScreenHeight(this));//奇酷1920。華爲1794
tv_info.append("\n狀態欄高度:" + DensityUtils.getStatusBarHeight(this));//奇酷72。華爲75
//須要 root 權限,且可能會被360報毒
// DensityUtils.saveBitmap2Pic(DensityUtils.snapShotWithStatusBar(this), FILE_PATH + "1.png");
// DensityUtils.saveBitmap2Pic(DensityUtils.snapShotWithoutStatusBar(this), FILE_PATH + "2.png");
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
tv_info.append("\n標題欄高度:" + DensityUtils.getTitleBarHeight(this));//奇酷161。華爲168
}
}
}
演示效果
奇酷1080P 華爲1080P 華爲720P
狀態欄高度25dp*3=75
25dp*2=50
25dp*2.875=71.875
工具類
package com.bqt.pop;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;
public class DensityUtils {
//******************************************************************************************
// 單位轉換
//******************************************************************************************
/**像素密度*/
public static float getDisplayMetrics(Context context) {
return context.getResources().getDisplayMetrics().density;
}
/** dp 轉成爲 px */
public static int dp2px(Context context, float dpValue) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
}
/** px 轉成爲 dp */
public static int px2dp(Context context, float pxValue) {
return (int) (pxValue / getDisplayMetrics(context) + 0.5f);
}
/** sp轉px */
public static int sp2px(Context context, float spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, context.getResources().getDisplayMetrics());
}
/** px轉sp */
public static float px2sp(Context context, float pxVal) {
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
}
//******************************************************************************************
// 屏幕寬高
//******************************************************************************************
/** 獲取屏幕寬 */
public static int getScreenWidth(Context context) {
DisplayMetrics metric = new DisplayMetrics();
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
return metric.widthPixels;
}
/** 獲取屏幕高,包含狀態欄,但不包含某些手機最下面的【HOME鍵那一欄】,如1920屏幕只有1794 */
public static int getScreenHeight(Context context) {
DisplayMetrics metric = new DisplayMetrics();
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
return metric.heightPixels;
}
/** 獲取屏幕寬 */
public static int getScreenWidth2(Context context) {
Point point = new Point();
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
return point.x;
}
/** 獲取屏幕高,包含狀態欄,但不包含某些手機最下面的【HOME鍵那一欄】,如1920屏幕只有1794 */
public static int getScreenHeight2(Context context) {
Point point = new Point();
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
return point.y;
}
/** 獲取屏幕原始尺寸高度,包括狀態欄以及虛擬功能鍵高度 */
public static int getAllScreenHeight(Context context) {
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
try {
DisplayMetrics displayMetrics = new DisplayMetrics();
Method method = Class.forName("android.view.Display").getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
return displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
//******************************************************************************************
// 狀態欄、標題欄、虛擬按鍵
//******************************************************************************************
/** 狀態欄高度,單位px,通常爲25dp */
public static int getStatusBarHeight(Context context) {
int height = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
height = context.getResources().getDimensionPixelSize(resourceId);
}
return height;
}
/** 狀態欄高度,單位px,【注意】要在onWindowFocusChanged中獲取才能夠 */
public static int getStatusBarHeight2(Activity activity) {
Rect rect = new Rect();
//DecorView是Window中的最頂層view,能夠從DecorView獲取到程序顯示的區域,包括標題欄,但不包括狀態欄。因此狀態欄的高度即爲顯示區域的top座標值
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
return rect.top;
}
/**標題欄的高度,【注意】要在onWindowFocusChanged中獲取才能夠*/
public static int getTitleBarHeight(Activity activity) {
int contentTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
return contentTop - getStatusBarHeight(activity);
}
/**獲取 虛擬按鍵的高度 */
public static int getBottomBarHeight(Context context) {
return getAllScreenHeight(context) - getScreenHeight(context);
}
}
2017-7-27