Android屏幕的適配,是每一個Android工程師在開發過程中都會遇到的惱人的難題,其實我們看一下android設備就知道了,千奇百怪,萬種變化,在適配的時候就有點怵.
屏幕適配的原因:
由于Android系統的開放性,任何用戶、開發者、OEM廠商、運營商都可以對Android進行定制,修改成他們想要的樣子。而隨著支持Android系統的設備(手機、平板、電視、手表)的增多,設備碎片化、品牌碎片化、系統碎片化、傳感器碎片化和屏幕碎片化的程度也在不斷地加深
重要概念:
1. 屏幕尺寸、屏幕分辨率、屏幕像素密度
屏幕尺寸:屏幕對角線長度,單位是英寸,我們常說的多少多少寸,比如4.7存手機、5.7存手機,指的就是這個。
屏幕分辨率:如 1920×1080,是指在手機屏幕的像素點的個數,單位是px,1px = 1 像素點,一般是縱向像素× 橫向像素,意味著高有1920 個像素點,寬有1080 個像素點。表示物理屏幕區域內像素點的總和(切記:跟屏幕適配沒有任何關系),因為我們既可以把1920*1080的分辨率做到4.0的手機上,也可以把這個分辨率做到5.0英寸的手機上面,如果分辨率相同,手機屏幕越小越清晰
屏幕像素密度:是指每英寸上的像素點數,單位是dpi(dotper inch)。像素密度和屏幕尺寸和屏幕分辨率有關,它是由對角線的像素點數除以屏幕的大小得到的,關系如下:
屏幕像素密度算法
(單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。)
dp、dip、dpi、sp、px(pix)
dp:是Android 特有的,意為密度無關像素,Google 發布的BASELINE(基準線)為160,以此為基準。
dip:Density Independent Pixels,同dp一個意思,目前廢棄了,一般都寫dp。
dpi:即為屏幕像素密度的單位
sp:Scale-IndependentPixels的縮寫,可以根據文字大小首選項自動進行縮放。Google推薦我們使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,為避免精度損失,建議最好不要使用奇數和小數。
px(pix):就是我們常說的像素,就是屏幕中最小的一個顯示單元.不同設備顯示的效果相同
mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi
一般都是采用以下幾種解決方案:
解決方案看圖:
適配相關術語:
分辨率(eg):480X800,1280X720。表示物理屏幕區域內像素點的總和。(切記:跟屏幕適配沒有任何關系) 因為我們既可以把1280X720的分辨率做到4.0的手機上面。我也可以把1280X720的分辨率做到5.0英寸的手機上面,如果分辨率相同,手機屏幕越小越清晰。
px(pix):像素,就是屏幕中最小的一個顯示單元。不同設備顯示效果相同。
dpi(像素密度):即每英寸屏幕所擁有的像素數,像素密度越大,顯示畫面細節就越豐富。計算公式:像素密度=√{(長度像素數2+寬度像素數2)}/ 屏幕尺寸
(注:屏幕尺寸單位為英寸 例:分辨率為1280*720 屏幕寬度為6英寸 計算所得像素密度約等于245,屏幕尺寸指屏幕對角線的長度.)
dip: deviceindependent pixels ,設備獨立像素。不同設備有不同的顯示效果,這個和設備硬件有關。
屏幕適配方式:
- 圖片適配
在我們的Android工程目錄中有如下drawable/mipmap-*dpi目錄,這些目錄是用來適配不同分辨率手機的。
不同的目錄,代表手機不同的像素密度:
以下是Android系統的適配策略:
Android應用在查找圖片資源時會根據其分辨率自動從不同的文件目錄下查找。如果在低分辨的文件目錄中比如drawable-mdpi中沒有圖片資源,其他目錄中都有,當我們將該應用部署到mdpi分辨率的手機上時,那么該應用會查找分辨率較高目錄下的資源文件,如果較高分辨率目錄下也沒有資源則只好找較低目錄中的資源了。
1.尺寸適配
跟drawable目錄類似的,在Android工程的res目錄下有values目錄,這個是默認的目錄,同時為了適配不同尺寸手機我們可以創建一個values-1280x720的文件夾,同時將dimens.xml文件拷貝到該目錄下。
在dimens.xml中定義一個尺寸,如下圖所示。
在values-1280x720目錄中的dimens.xml中定義同樣的尺寸名稱,但是使用不同的尺寸,如下圖所示。
當我們在布局文件中使用長或者寬度單位時,比如下圖所示,應該使用@dimen/width來靈活的定義寬度。
- 布局適配-(這種適配幾乎不常見)
跟values一樣,在Android工程目錄中layout目錄也支持類似values目錄一樣的適配,在layout中我們可以針對不同手機的分辨率制定不同的布局,如下圖所示。
權重適配(谷歌推薦)
在控件中使用屬性android:layout_weight="1"可以起到適配效果,但是該屬性的使用有如下規則: 只能用在線性控件中,比如LinearLayout。 豎直方向上使用權重的控件高度必須為0dp(Google官方的推薦用法) 水平方向上使用權重的控件寬度必須為0dp(Google官方的推薦用法)代碼適配
在java代碼中動態計算控件的寬度和高度。 注意:計算的寬度和高度,這里涉及到dp和px之間的轉化:
說明一下dp代表什么意思? dip: deviceindependent pixels(設備獨立像素)。不同設備有不同的顯示效果,這個和設備硬件有關。這里指一個抽象意義上的像素,程序用它來定義界面元素。一個與密度無關,在邏輯尺寸上,與一個位于像素密度為160dpi的屏幕上的像素是一致的。
要把密度無關像素轉換為屏幕像素可以用這樣一個簡單的公式:pixels=dips*(density/160)。
舉個例子,在DPI為240的屏幕上,1個DIP等于1.5個物理像素。
代碼中相互換算:
- 百分比適配
該適配一般對圖片進行適配的。 比如:在同一張圖片,在不同的設備中,按照圖片的寬高比例,進行縮放顯示。
- 獲取圖片的寬度和高度
- 計算圖片的寬度和高度的比例
- 根據圖片的比例,計算出圖片的在設備中的顯示的實際寬度和高度
關于切圖數量的分析:
跟UI人員要求,對于主流的手機機型分辨率,選1至2套完整的一套圖片(比如1920×1080分辨率是主流機型),這一套圖必須是完整的,但是對于平鋪整個界面的大圖需要多切幾套,比如說歡迎界面,幫助界面等之類的圖片,針對于小圖的話就只需要一套左右就夠了,因為小圖在屏幕上的稍微拉伸,人的視覺效果是很難感覺到的,在android studio圖片目錄結構中,編譯工具找圖的順序是當找不到的時候,先往高分辨率,再往低分辨率找.
為什么我們要將對應分辨率的圖片放入對應文件夾?(根據以下圖片進行分析)
三星手機拍照有哪些bug?
攝像頭拍照后圖片數據有可能不能返回; 應該是onActivityResult 的data為空
三星手機的相機camera強制切換到橫屏,導致Activity重啟生命周期(部分機型即使配置android:configChanges也不能阻止橫豎屏切換)
APP Activity A調用了系統拍照-->拍照-->在拍好照片的界面做幾次橫豎屏的轉換后-->返回APP界面時,Activity A卻被銷毀了
平時開發過程中,如何做到多分辨適配的?
- 首先明確開發設備分辨率:一般選擇1920*1080的分辨率(市面上主流的手機分辨率)
- 根據分辨率的不同建立不同分辨率的資源圖片(可以根據切圖的數量進行分析)
- 在程序啟動的時候,獲取當前屏幕的分辨率和密度,在代碼中進行適配
- 根據目標設備,為不同分辨率的寫不同的dimen文件
- 盡量使用權重分配(Google推薦)
- 根據需求可以使用代碼適配以及百分比適配
- 針對特殊的設備,進行特殊的適配