Android 手機(jī)屏幕適配解決辦法
0. 前言
Android的屏幕適配,即使得某一元素在Android不同尺寸、不同分辨率的手機(jī)上具備相同的顯示效果,這個(gè)問題一直以來都是我們Android開發(fā)者不得不面對(duì)的問題。本文參考了很多前人的博客,并對(duì)這一問題做一個(gè)總結(jié),力求精簡(jiǎn)明了。
轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/seu_calvin/article/details/52690498
1. 基礎(chǔ)概念
(1)屏幕尺寸,即手機(jī)對(duì)角線的物理尺寸
1英寸 = 2.54cm 常見手機(jī)尺寸有5英寸、5.5英寸、6英寸等。
(2)屏幕分辨率,即手機(jī)在橫向、縱向上的像素點(diǎn)數(shù)總和(一般描述成屏幕的”寬x高”)
例如1080dpx1920dp,即寬度方向上有1080個(gè)像素點(diǎn),在高度方向上有1920個(gè)像素點(diǎn),1px=1像素點(diǎn)
Android手機(jī)常見的分辨率:320x480、480x800、720x1280、1080x1920
(3)屏幕像素密度,即每英寸的像素點(diǎn)數(shù),單位dpi
例如某設(shè)備為240x320,屏幕尺寸為3.3英寸,那么該設(shè)備的屏幕像素密度為400/3.3=120dpi,其中400為通過寬高像素勾股定理得出。
Android手機(jī)根據(jù)像素密度,可以分為以下幾種屏幕密度類型:

(4)密度無關(guān)像素,單位為dp,是Android特有的單位
Android開發(fā)時(shí)通常使用dp而不是px單位設(shè)置圖片大小,因?yàn)樗梢员WC在不同屏幕像素密度的設(shè)備上顯示相同的效果。
/**
* dp與px的轉(zhuǎn)換
* Created by SEU_Calvin on 2016/09/28
*/
public class DensityUtils {
public static int dp2px(float dp , Context context){
float density = context.getResources().getDisplayMetrics().density;//即表中的0.75/1/1.5/2/3
//context.getResources().getDisplayMetrics().densityDpi //即表中的120/160/240/320/480
return (int)(dp * density + 0.5f);
}
public static float px2dp(int px , Context context){
float density = context.getResources().getDisplayMetrics().density;
return px/density;
}
}
(5)獨(dú)立比例像素,單位為sp,Android開發(fā)時(shí)用于設(shè)置文字大小的單位
可根據(jù)字體大小首選項(xiàng)進(jìn)行縮放,推薦使用12/14/18/22sp作為字體設(shè)置的大小,不推薦使用奇數(shù)和小數(shù),容易造成精度的丟失問題。
介紹了上述基礎(chǔ)概念,我們接下來從布局適配、圖片適配、以及代碼適配三個(gè)角度分別介紹屏幕適配的解決方案。
2. 布局適配
(1)推薦使用相對(duì)布局,禁用絕對(duì)布局。因?yàn)橄鄬?duì)布局在屏幕的大小改變時(shí)視圖之間的相對(duì)位置不會(huì)變化。
(2)使用dp和sp(盡量不用px)、wrap_content、match_parent和weight來控制布局。使用權(quán)重weight在任何設(shè)備上均會(huì)完美適配。
(3)為不同屏幕尺寸的設(shè)備設(shè)計(jì)不同的布局,通過配置限定符使得程序在運(yùn)行時(shí)根據(jù)當(dāng)前設(shè)備的尺寸自動(dòng)加載合適的布局資源。
比如我們先寫兩個(gè)布局文件,分別為:
適配手機(jī)的布局(默認(rèn)):res/layout/main.xml
適配尺寸>7寸平板的布局:res/layout/main_pb.xml
然后加入以下兩個(gè)文件,系統(tǒng)會(huì)根據(jù)Android版本自動(dòng)選擇使用哪個(gè)布局配置文件。
//適配Android 3.2之前的平板布局 res/values-large/layout.xml <resources> <item name="main" type="layout">@layout/main_pb</item> </resources> //適配Android 3.2之后的平板布局 res/values-sw600dp/layout.xml <resources> <item name="main" type="layout">@layout/main_pb</item> </resources>
上述兩個(gè)配置文件,并沒有真正去定義布局,它們僅僅是將main設(shè)置成了@layout/main_pb的別名。
如果不這樣做,main_pb.xml布局文件的內(nèi)容需要復(fù)制成兩份分別放入res/layout-large/main.xml和res/layout-sw600dp/main.xml以適配3.2以前和以后,這樣明顯很冗余。
3. 圖片適配
(1)比如有一個(gè)這樣的需求,一個(gè)按鈕的背景圖片必須能夠隨著按鈕大小的改變而改變。使用普通的圖片將無法實(shí)現(xiàn)上述功能,因?yàn)檫\(yùn)行時(shí)會(huì)均勻地拉伸或壓縮你的圖片。
這時(shí)候可以使用Nine-Patch圖(一種被特殊處理過的PNG圖片,使用.9.png后綴名),9Patch圖可以指定圖片的拉伸區(qū)域和非拉伸區(qū)域,在需要拉伸圖片時(shí),系統(tǒng)就會(huì)自動(dòng)地拉伸你想要拉伸的部分。需要注意的是,.9圖不需要多個(gè)分辨率的圖片,放在drawable文件夾即可。

紅色框區(qū)域:表示縱向拉伸的區(qū)域,也就是說,當(dāng)圖片需要縱向拉伸的時(shí)候它會(huì)只指定拉伸紅色區(qū)域。
綠色框區(qū)域:表示橫向拉伸的區(qū)域,也就是說,當(dāng)圖片需要橫向拉伸的時(shí)候它會(huì)只指定拉伸綠色區(qū)域。
(2)圖片不需要在下圖hdpi、mdpi等目錄下都放入相對(duì)應(yīng)的分辨率的圖片,這樣會(huì)使APK變大,一般只做1280*720一套圖,放在hdpi或xhdpi下,若出問題再針對(duì)屏幕進(jìn)行問題圖片替換即可。另外對(duì)于如何減小APK大小,可以參考Android開發(fā)——減小APK大小。
3. 代碼適配
(1)比如有一個(gè)需求,需要實(shí)現(xiàn)一個(gè)空間寬度,是屏幕的1/3。這時(shí)候就可以用代碼實(shí)現(xiàn):
/** * 代碼適配例子 * Created by SEU_Calvin on 2016/09/28 */ WindowManager wm = getWindowManager(); int width = wm.getDefaultDisplay().getWidth(); LinearLayout.LayoutParams params = (LayoutParams)tv.getLayoutParams(); params.width = width/3; tv.setLayoutParams(params);
需要注意的是,一般代碼適配需要寫一個(gè)工具類(上文中已經(jīng)貼出了)來實(shí)現(xiàn)dp2px ,因?yàn)榇a里的參數(shù)一般都需要px值,需要通過不同設(shè)備的屏幕密度來實(shí)現(xiàn)dp2px。
(2)代碼適配的另一個(gè)使用場(chǎng)景是根據(jù)加載布局的不同,來決定走不同的流程,如下:
setContentView(R.layout.main_layout);//此處會(huì)根據(jù)屏幕大小加載不同的布局
Button btn = (Button)findViewById(R.id.btn);//其中一個(gè)布局沒有該按鈕
if(btn == null){
//業(yè)務(wù)邏輯1...
}else{
//業(yè)務(wù)邏輯2...
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Android實(shí)現(xiàn)毛玻璃效果的對(duì)話框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)毛玻璃效果的對(duì)話框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Android實(shí)現(xiàn)多維商品屬性SKU選擇
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)多維商品屬性SKU選擇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
Android實(shí)現(xiàn)絢麗的自定義進(jìn)度條
進(jìn)度條是在Android項(xiàng)目中很常用的組件之一,本文將為大家詳細(xì)地介紹一下自定義進(jìn)度條的實(shí)現(xiàn)過程。感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-01-01
Android RecyclerView詳解之實(shí)現(xiàn) ListView GridView瀑布流效果
RecyclerView 是Android L版本中新添加的一個(gè)用來取代ListView的SDK,它的靈活性與可替代性比listview更好2016-07-07
Android利用ViewPager實(shí)現(xiàn)滑動(dòng)廣告板實(shí)例源碼
利用ViewPager我們可以做很多事情,從最簡(jiǎn)單的導(dǎo)航,到頁面切換菜單等等。ViewPager的功能就是可以使視圖滑動(dòng),就像Lanucher左右滑動(dòng)那樣2013-06-06
完美解決Android Studio集成crashlytics后無法編譯的問題
下面小編就為大家?guī)硪黄昝澜鉀QAndroid Studio集成crashlytics后無法編譯的問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05

