螢幕尺寸
螢幕尺寸指螢幕的對角線的長度,機關是英寸,1英寸=2.54厘米(下面有圖文介紹)
比如常見的螢幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等
螢幕分辨率
螢幕分辨率是指在橫縱向上的像素點數,機關是px,1px=1個像素點。一般以縱向像素*橫向像素,如1960*1080。
螢幕像素密度
螢幕像素密度是指每英寸上的像素點數,機關是dpi,即“dot per inch”的縮寫。螢幕像素密度與螢幕尺寸和螢幕分辨率有關,在單一變化條件下,螢幕尺寸越小、分辨率越高,像素密度越大,反之越小。
- 當裝置的實體尺寸存在差異的時候,dp就顯得無能為力了。為4.3寸螢幕準備的UI,運作在5.0寸的螢幕上,很可能在右側和下側存在大量的空白。而5.0寸的UI運作到4.3寸的裝置上,很可能顯示不下。
一句話,總結下,dp能夠讓同一數值在不同的分辨率展示出大緻相同的尺寸大小。 但是當裝置的尺寸差異較大的時候 ,就無能為力了。适配的問題還需要我們自己去做,于是我們可能會這麼做:
上述代碼片段來自網絡,也就是說,我們為了優質的使用者體驗,依然需要去針對不同的dpi設定,編寫多套數值檔案。
可以看出,dp并沒有能解決适配問題。下面看百分比。
我們再來看看一些适配的tips
- 多用match_parent
- 多用weight
- 自定義view解決
其實上述3點tip,歸根結底還是利用百分比,match_parent相當于100%參考父控件;weight即按比例配置設定;自定義view無非是因為裡面多數尺寸是按照百分比計算的;
dp: Density-independent pixel (dp)獨立像素密度。标準是160dip.即1dp對應1個pixel,計算公式如:px = dp * (dpi / 160),螢幕密度越大,1dp對應 的像素點越多。
上面的公式中有個dpi,dpi為DPI是Dots Per Inch(每英寸所列印的點數),也就是當裝置的dpi為160的時候1px=1dp;
計算值
ppi的運算方式是:
PPI = √(長度像素數² + 寬度像素數²) / 螢幕對角線英寸數
dp:Density-independent pixels,以160PPI螢幕為标準,則1dp=1px,
dp和px的換算公式 :
dp*ppi/160 = px。比如1dp x 320ppi/160 = 2px。
螢幕尺寸、分辨率、像素密度三者關系(以上三者的關系)
像素密度的公式
一部手機的分辨率是寬x高,螢幕大小是以寸為機關,那麼三者的關系是:
假設一部手機的分辨率是1080x1920(px),螢幕大小是5寸,問密度是多少?
像素密度計算公式
螢幕多少英寸指的是對角線的長度。像素密度是指(以1920×1080,5英寸為例),1920和1080的平方和開根号(就是直角三角形斜邊長的算法),開出來等于2202.9,除以5英寸就得到ppi441左右
例:"HTC One(32GB/單卡/國際版)
4.7英寸螢幕,分辨率1920x1080 求解像素密度?
解:√(1920^2+1080^2)=2202.9071
2202.9/5=468.7021(ppi)≈469ppi
答:此螢幕像素密度約是469ppi.
因為ui設計師給你的設計圖是以px為機關的,Android開發則是使用dp作為機關的,那麼我們需要進行轉換:
密度類型 | 代表的分辨率(px) | 螢幕密度(dpi) | 換算(px/dp) | 比例 |
---|---|---|---|---|
低密度(ldpi) | 240x320 | 120(最大) | 1dp=0.75px | 3 |
中密度(mdpi) | 320x480 | 160(最大) | 1dp=1px | 4 |
高密度(hdpi) | 480x800 | 240(最大) | 1dp=1.5px | 6 |
超高密度(xhdpi) | 720x1280 | 320(最大) | 1dp=2px | 8 |
超超高密度(xxhdpi) | 1080x1920 | 480(最大) | 1dp=3px | 12 |
為了保證使用者獲得一緻的使用者體驗效果:使得某一進制素在Android不同尺寸、不同分辨率的手機上具備相同的顯示效果 在進行開發的時候,我們需要把合适大小的圖檔放在合适的檔案夾裡面。下面以圖示設計為例進行介紹。
下圖為圖示的各個螢幕密度的對應尺寸:
1).使用自動拉伸位圖 .9圖檔 2).請務必使用 sp 指定文字大小: 3).使用布局别名
最小寬度限定符僅适用于 Android 3.2 及更高版本。是以,如果我們仍需使用與較低版本相容的概括尺寸範圍(小、正常、大和特大)。例如,如果要将使用者界面設計成在手機上顯示單面闆,但在 7 英寸平闆電腦、電視和其他較大的裝置上顯示多面闆,那麼我們就需要提供以下檔案:
- res/layout/main.xml: 單面闆布局
- res/layout-large: 多面闆布局
- res/layout-sw600dp: 多面闆布局
後兩個檔案是相同的,因為其中一個用于和 Android 3.2 裝置比對,而另一個則是為使用較低版本 Android 的平闆電腦和電視準備的。
要避免平闆電腦和電視的檔案出現重複(以及由此帶來的維護問題),您可以使用别名檔案。例如,您可以定義以下布局:
- res/layout/main.xml,單面闆布局
- res/layout/main_twopanes.xml,雙面闆布局
然後添加這兩個檔案:
res/values-large/layout.xml:
res/values-sw600dp/layout.xml:
後兩個檔案的内容相同,但它們并未實際定義布局。它們隻是将 main 設定成了 main_twopanes 的别名。由于這些檔案包含 large 和 sw600dp 選擇器,是以無論 Android 版本如何,
系統都會将這些檔案應用到平闆電腦和電視上(版本低于 3.2 的平闆電腦和電視會比對 large,版本高于 3.2 的平闆電腦和電視則會比對 sw600dp)。
圖檔的适配方案: 什麼叫最适合的圖檔?比如我的手機螢幕密度是xxhdpi,那麼drawable-xxhdpi檔案夾下的圖檔就是最适合的圖檔。 縮放原理: 例如,一個啟動圖示的尺寸為48x48 dp,這表示在 MDPI 的螢幕上其實際尺寸應為 48x48 px,在 HDPI 的螢幕上其實際大小是 MDPI 的 1.5 倍 (72x72 px),
在 XDPI 的螢幕上其實際大小是 MDPI 的 2 倍 (96x96 px),依此類推。
雖然 Android 也支援低像素密度 (LDPI) 的螢幕,但無需為此費神,系統會自動将 HDPI 尺寸的圖示縮小到 1/2 進行比對。
放大系數的關系:和螢幕像素密度有關
mdpi密度的最高dpi值是160,而xxhdpi密度的最高dpi值是480,是以是一個3倍的關系。放大系數和檔案夾的密度有關系! xxxhdpi密度的最高dpi值是640,480是它的0.75倍 正常Xhdpi的圖檔,如果放在了xxhdpi裡面,圖檔會縮小,放在hdpi的裡面圖檔會放大! 一張原圖檔被縮小了之後顯示其實并沒有什麼副作用,但是一張原圖檔被放大了之後顯示就意味着要占用更多的記憶體了。 但是一張原圖檔被放大了之後顯示就意味着要占用更多的記憶體了。因為圖檔被放大了,像素點也就變多了,而每個像素點都是要占用記憶體的。 我們仍然可以通過例子來直覺地體會一下,首先将android_logo.png圖檔移動到drawable-xxhdpi目錄下,運作程式後我們通過Android Monitor來觀察程式記憶體使用情況: 可以看到,程式所占用的記憶體大概穩定在19.45M左右。然後将android_logo.png圖檔移動到drawable-mdpi目錄下,重新運作程式,結果如下圖所示: 現在漲到23.40M了,占用記憶體明顯增加了。如果你将圖檔移動到drawable-ldpi目錄下,你會發現占用記憶體會更高。 通過這個例子同時也驗證了一個問題,我相信有不少比較有經驗的Android程式員可能都遇到過這個情況,就是當你的項目變得越來越大, 有的時候加載一張drawable-hdpi下的圖檔,程式就直接OOM崩掉了,但如果将這張圖放到drawable-xhdpi或drawable-xxhdpi下就不會崩掉,其實就是這個道理。 那麼經過上面一系列的分析,答案自然也就出來了 ,圖檔資源應該盡量放在高密度檔案夾下,這樣可以節省圖檔的記憶體開支,而UI在設計圖檔的時候也應該盡量面向高密度螢幕的裝置來進行設計。 就目前來講, 最佳放置圖檔資源的檔案夾就是drawable-xxhdpi。那麼有的朋友可能會問了,不是還有更高密度的drawable-xxxhdpi嗎?幹嗎不放在這裡? 這是因為,市面上480dpi到640dpi的裝置實在是太少了,如果針對這種級别的螢幕密度來設計圖檔,圖檔在不縮放的情況下本身就已經很大了, 因為分辨率不一樣,是以不能用px;因為螢幕寬度不一樣,是以要小心的用dp,那麼我們可不可以用另外一種方法來統一機關,不管分辨率是多大,螢幕寬度用一個固定的值的機關來統計呢? 百分比适配方法,對于控件的寬和高!
<TextView
android:layout_width="@dimen/x360"
android:layout_height="@dimen/x360"
android:background="@color/colorAccent"
android:gravity="center"
android:text="360x360"/>
<TextView
android:layout_width="@dimen/x180"
android:layout_height="@dimen/x180"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="180x180"/>
<dimen name="x356">356px</dimen>
<dimen name="x357">357px</dimen>
<dimen name="x358">358px</dimen>
<dimen name="x359">359px</dimen>
<dimen name="x360">360px</dimen>
<dimen name="x358">537px</dimen>
<dimen name="x359">538.5px</dimen>
<dimen name="x360">540px</dimen>
<dimen name="x361">541.5px</dimen>
<dimen name="x362">543px</dimen>
<dimen name="x363">544.5px</dimen>
總結: 不同分辨率的檔案夾有不同x360的px值,是通過程式計算自動生成的!
适配缺點:
是以說,這個方案雖然是一勞永逸,但是由于實際上還是使用的px作為長度的度量機關,是以多少和google的要求有所背離,不好說以後會不會出現什麼不可預測的問題。 其次,如果要使用這個方案,你必須盡可能多的包含所有的分辨率,因為這個是使用這個方案的基礎,如果有分辨率缺少,會造成顯示效果很差,甚至出錯的風險,而這又勢必會增加軟體包的大小和維護的難度, 是以大家自己斟酌,擇優使用。
- 對于沒有考慮到螢幕尺寸,可能會出現意外的情況;
- apk的大小會增加;
注意的問題: 要有一個通用的布局,不然有些手機會報錯!
虛拟按鍵的問題
設計高度 = 螢幕高度 - 狀态欄高度
布局高度 = 螢幕高度 - 狀态欄高度 - 虛拟按鍵高度
要解決這個問題,其實很簡單,我說過,這不是一個技術問題,是以不必使用 fitsSystemWindows 屬性,也避免了副作用。
隻需要在布局時,正确了解設計師的意圖,比如,如果一個按鈕在最底部,你應該用 layout_gravity="bottom" 而不是用 marginTop 或者其他方式來把它撐到底部。
我開始以為他們是導航欄上的虛拟按鍵,因為确實我将按鍵隐藏後可以成功适配,然後我就在網上通過如下代碼來擷取他們的真實分辨率
/**
* @param context
* @return 擷取螢幕原始尺寸高度,包括虛拟功能鍵高度
*/
public static int getTotalHeight(Context context) {
int dpi = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
dpi = displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return dpi;
}
/**
* @param context
* @return 擷取螢幕内容高度不包括虛拟按鍵
*/
public static int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
這裡我用了三部華為手機通過上面的方法擷取分辨率
華為榮耀8 1080 1920 得到1080 1812
華為暢享5 720 1280 得到720 1184
華為暢玩5x 108 1920 得到 1080 1776
通過這兩個方法我們可以得到手機的分辨率高度和手機去除虛拟按鍵的高度,兩者相減就是手機的虛拟按鍵的高度
調用後得到的結果是 總高度 : 2560 内容高度 : 2408 虛拟按鍵 : 152
如果想要适配該機型,其實也很簡單,隻需要把原來的values-2560x1440檔案夾複制一份重新名為values-2408x1440即可,
http://blog.csdn.net/c15522627353/article/details/52452490
Google的 百分比布局庫(percent-support-lib)
PercentRelativeLayout、PercentFrameLayout,不過貌似沒有LinearLayout,有人會說LinearLayout有weight屬性呀。但是,weight屬性隻能支援一個方向呀~~哈,沒事,剛好給我們一個機會去 自定義一個PercentLinearLayout。
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent">
<Viewandroid:id="@+id/top_left"android:layout_width="0dp"android:layout_height="0dp"android:layout_alignParentTop="true"android:background="#ff44aacc"app:layout_heightPercent="20%"app:layout_widthPercent="70%" />
<Viewandroid:id="@+id/top_right"android:layout_width="0dp"android:layout_height="0dp"android:layout_alignParentTop="true"android:layout_toRightOf="@+id/top_left"android:background="#ffe40000"app:layout_heightPercent="20%"app:layout_widthPercent="30%" />
<Viewandroid:id="@+id/bottom"android:layout_width="match_parent"android:layout_height="0dp"android:layout_below="@+id/top_left"android:background="#ff00ff22"app:layout_heightPercent="80%" />
</android.support.percent.PercentRelativeLayout>
Android UI适配小結:
1.一般情況下,輸出 幾套 ,各為 多少分辨率 不同的品質的 切圖 ?
2.一般情況下,輸出 幾套 分辨率不同的 标注圖 (如常說的主流四套分辨率,1080*1920,720*1280,480*800.240*320), 标注機關為 px 還是自己計算的 dp (這個機關您一般是自己計算還是交給程式,如果自己計算的話比較好的方法),建立畫布時第一版從 多少分辨率 的畫布開始設計。
3.是否考慮帶有 虛拟按鍵 的适配不同方法?
4.遇到與主流分辨率 相近 但 長寬比不同 的分辨率時的适配方式。
5. 字号 的适配方式,字号 機關 。
6.與程式 适配 溝通時需要注意的 要點 。
7.其它我未提及或者沒考慮到的但您覺得非常 重要的問題 。
1.一般隻輸出主流尺寸的切圖,如480*800 1280*720
2.開發寫标準尺寸是按照320P來的,得按照你自己的設計稿來标注,不過得算好比例:比如你出了480*800的設計稿,你所有的标注的所有尺寸都得除以1.5;要是出了720*1280的設計稿,你所有的标注的所有尺寸都得除以2,以此類推
3.無需考慮,系統自适應
4.隻要寬度分辨率一樣,适配一樣
5.字号跟第2點一樣道理
6.程式員對UI實作都不嚴謹(因為他們覺得UI不重要),要時時刻刻盯着
主流APP: 對于平闆來說:都是要單獨一套App的
而分辨率可以以1280*720或者是1960*1080作為主要分辨率進行設計。
1280:720 的屏占比 16:9 1960*1280的屏占比 49:32
效果圖一套(720p),切圖也是 720p (有時候要求1080p,看公司要求高不高)。
UI切圖都是以1280*720 開發寫标準尺寸是按照320P來的
假若還是不适配的話也可以根據不适配的機型來設定特别的值。
為什麼Web頁面設計人員從來沒有說過,尼瑪适配好麻煩?
其實就是一個原因, 網頁提供了百分比計算大小。
自定義控件以PX為機關計算的,那麼怎麼适配呢!
SVG
适配參考 http://blog.csdn.net/zhaoyw2008/article/details/46008513
虛拟按鍵的适配 http://blog.csdn.net/guozhaohui628/article/details/71870530
http://blog.csdn.net/github_2011/article/details/72636851