Android 手機的尺寸類別特別多.因此我們爲了讓我們開發的APP在各種尺寸的Android 手機上都可以展示完美的UI .就用到了屏幕適配.
基礎概念
1. 屏幕尺寸
屏幕尺寸指的是屏幕對角線的長度, 單位是英寸 , 1英寸= 2.54釐米.
比如常見的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等
2. 屏幕分辨率
屏幕分辨率是指在橫/縱方向上的像素點數, 單位是 px , 1 px = 1個像素點, 一般使用 : 縱向像素*橫向像素 1960 * 1080.
3. 屏幕像素密度
屏幕像素密度是指每英寸上的像素點數 . 單位是 dpi (dot per inch) . 屏幕像素密度與屏幕尺寸和屏幕分辨率有關 , 在分辨率相同的情況下屏幕尺寸越小屏幕像素密度就越大.
4. 相關的單位概念
- dp/dip
dip和dp是一個意思,都是Density Independent Pixels的縮寫,即密度無關像素. 在屏幕像素密度DPI = 160 dpi , 此時 1sp = 1px. Android規定以160dpi位基準 , 也就是所在此種情況下 1px = 1dp. 如在320dpi 下 1dp = 2px. 一次類推 - dpi
屏幕像素密度. 每英寸上的像素點個數. - sp
sp,即scale-independent pixels,與dp類似,但是可以根據文字大小首選項進行放縮, 是設置字體大小的御用單位. - px
px 就是像素, 前面的分辨率就是使用的px作爲單位. 在大多數情況下, UI設計 , Android 原生API都會以px作爲單位.比如過去P屏幕的寬高.
// 獲取屏幕尺寸
private void getScreenSize(){
WindowManager wm =
(WindowManager) getSystemService(Context.WINDOW_SERVICE);
final int sw = wm.getDefaultDisplay().getWidth();
final int sh = wm.getDefaultDisplay().getHeight();
Log.d(TAG, "Size : " + sh + "px * " + sw + "px");
}
// 輸出 : Size : 1184px * 768px
5. 尺寸限定符
名稱 | 像素密度值範圍 | 比例 |
---|---|---|
mdpi | 120dpi ~ 160dpi | 2 |
hdpi | 160dpi ~ 1240dpi | 3 |
xdpi | 240dpi ~ 320dpi | 4 |
xxdpi | 320dpi ~ 480dpi | 6 |
xxxdpi | 480dpi ~ 640dpi | 8 |
在開發的時候我們需要將圖片放到合適的文件夾中
在設計圖標時,對於五種主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)應按照 上表所示的比例進行縮放. 比如啓動圖標的尺寸是 48 * 48 dp . 實際像素尺寸如下表.
屏幕尺寸 | 圖標尺寸 | 比例 |
---|---|---|
mdpi | 48 * 48 | 2 |
hdpi | 72 8 72 | 3 |
xdpi | 96 * 96 | 4 |
xxdpi | 144 * 144 | 6 |
xxxdpi | 192 * 192 | 8 |
屏幕適配解決方案
1. 支持各種屏幕尺寸.
1.1 wrap_content
使用 “wrap_content” 屬性,系統會根據內容所需要的尺寸設置空間的大小,但是不會超過父控件的剩餘空間大小.
1.2 match_parent
使用 “match_parent” (在API 8以下使用fill_parent) 會讓組件佔據浮父控件的剩餘可用空間. 如下圖.
1.3 weight
weight屬性我們可以看成是按比例分配尺寸 . 但是這個屬性只能用在線性佈局中. 比如一個水平方向的線性佈局有兩個子空間. 將他們的寬度設置成 0 dp 分別設置weight 爲1 和 2. 則他們會以 1:2 佔據父控件所有的剩餘空間.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:background="#0f0"
android:textSize="20sp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="weight=1"/>
<TextView
android:background="#f00"
android:textSize="20sp"
android:maxLines="1"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="weight=2"/>
</LinearLayout>
android:layout_weight
的真實含義是 : 如果View設置了該屬性並且有效 , 那麼該View的寬度等於原有寬度 加上剩餘空間的佔比.
實際尺寸 = 原有尺寸 + 父控件剩餘尺寸佔比.
比如上面的例子.當寬度設置爲 0dp時 此時就有
剩餘空間 = L- (0 + 0) = L
weight = 1 的控件的寬度 = 0 + L * (1/(1 + 2)) = (1/3)L
weight = 2 的控件的寬度 = 0 + L * (2/(1 + 2)) = (2/3)L
我們現在講兩個的控件的寬度都設置成match_parent 此時的效果圖如下,
從上圖可以看出比例正好和反了,這是怎麼回事呢. 其實這是正常的.我們現在按照上面的公式計算一下.
由於使用的是match_parent
所以兩個View的原來寬度都是父控件的寬度也就是 L , 所以有如下結果
剩餘空間 = L- (L + L) = -L
weight = 1 的控件的寬度 = L + ( - L * (1/(1 + 2))) = (2/3)L
weight = 2 的控件的寬度 = L + ( -L * (2/(1 + 2)) = (1/3)L
所以上面的現象是正常的.
2. 使用相對佈局,儘量不用絕對佈局
在開發中我們儘量使用 線性佈局 , 相對佈局 和幀佈局 , 儘量不要使用據對佈局因爲他的適配性特別差.
使用相對佈局可以實現控件之間的複雜位置關係.
這裏就不做舉例了.