Android螢幕適配實踐總結
##名詞解釋
####px (pixels) 最為熟悉的畫素,設計圖以此為單位標註;
####dp或dip (device independent pixels) 裝置獨立畫素,與裝置螢幕有關,Android的UI標註以此為單位可最大限度適配不同解析度;
####sp (scaled pixels — best for text size):類似dp, 主要處理字型的大小;
dpi (dots per inch)螢幕畫素密度,描述螢幕畫素整合度。
##單位換算
Android規定以160dpi為標註,此時1dp=1px,如果畫素密度為320dpi,則1dp=2px,以此類推。
##畫素密度分組
參考連結 http://www.cocoachina.com/android/20151030/13971.html
將切圖放到對應的分組資料夾,系統會自動去適配。
##舉例
假設設計圖為1920px1080px的標註圖,需要執行的裝置為1280px720px ,dpi=160
1、首先按標註圖設定各標註尺寸,放到res\values\dimens.xml檔案中,此檔案中預設為160dpi的尺寸,即1dp=1px,直接按標註圖寫標註值即可;
2、需要適配的裝置尺寸換算,由於dpi不變,仍為160dpi,但解析度變小,在原尺寸上全部乘以係數(1280/1920)/1=2/3=0.666667(末尾會附上轉換的程式碼),將轉換後的dimens.xml檔案放到res\values-sw720dp資料夾下,該檔案及表示最小螢幕寬度為720dp的裝置會在這個資料夾找配置檔案;
3、160dpi對應的畫素密度分組為hdpi,需要將切圖放到res\drawable-hdpi資料夾下;
4、切圖和轉換後的dimens.xml檔案放到對應的資料夾就完成了該裝置的適配。
備註:如果要適配到1920*1080px,240dpi的裝置(1.5x)上,dimens.xml的換算係數為(1920/1920)/1.5=2/3=0.6667
檢視裝置螢幕引數:
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int dpi = displayMetrics.densityDpi;//dpi值,如160, 240
double density = displayMetrics.density;//以160dpi為基準的畫素密度,如1x,1.5x,2x等
int width = displayMetrics.widthPixels; //螢幕解析度寬度,單位px,如1920px
int height = displayMetrics.heightPixels;//螢幕解析度高度,單位px,如1080px
Configuration cfg = getResources().getConfiguration();
int smallScreenWidth = cfg.smallestScreenWidthDp;//最小螢幕寬度,如720dp,系統就是根據該值去查詢到底需要哪一個dimens.xml檔案,例如720dp的裝置會使用res\values-sw720dp資料夾下的dimens.xml
//如果需要測試設定讀取到的值為多少,可以加類似如下列印
Log.i(TAG,"left="+Math.round(getResources().getDimension(R.dimen.margin_left)));
一般我們需要知道的資訊是dpi和最小螢幕寬度,即可完成適配。
##總結:
1、res\values\dimens.xml檔案中存放的是160dpi基準尺寸,根據裝置的不同需要換算適配不同的尺寸,換算後放到對應的資料夾中,如res\values-sw720dp限定符為最小螢幕寬度為720dp的裝置會使用此資料夾下的配置尺寸;
2、根據dpi的不同,將切圖放到對應的資料夾下,如160dpi~240dpi的裝置都可將切圖放到res\drawable-hdpi資料夾
3、儘可能的使用match_parent, fill_parent, wrap_content來設定控制元件寬高,少用dp設定寬高,dp只用於設定邊距,避免使用px;
##附件:
####尺寸轉換程式碼
package pxTodp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 這個類用於將設計圖上的畫素值,轉換為Android裡面的dp
* 用法:1、在values資料夾的dimens.xml中按設計圖填寫邊距及位置值,單位為dp
* 2、利用此工具將dimens.xml轉為為新的值,轉換倍數自定義
*/
public class DimenTool {
private static final String SOURCE_FILE_NAME = "dimens.xml";//注意檔案路徑,是否能找到該檔案,可以將該類提取到eclipse中單獨執行
private static final String DES_FILE_NAME = "dimens_720.xml";
private static final double MULTIPLE = 2.0/3.0;//設計圖為1920*1080轉換為1280*720
public static void gen() {
File file = new File("dimens.xml");
BufferedReader reader = null;
StringBuilder sw720 = new StringBuilder();
try {
System.out.println("生成不同解析度:");
reader = new BufferedReader(new FileReader(file));
String tempString;
int line = 1;
// 一次讀入一行,直到讀入null為檔案結束
while ((tempString = reader.readLine()) != null) {
if (tempString.contains("</dimen>")) {
String start = tempString.substring(0, tempString.indexOf(">") + 1);
String end = tempString.substring(tempString.lastIndexOf("<") - 2);
int num = Integer.valueOf(tempString.substring(tempString.indexOf(">") + 1, tempString.indexOf("</dimen>") - 2)).intValue();
sw720.append(start).append((int) Math.round(num * MULTIPLE)).append(end).append("\n");
} else {
sw720.append(tempString).append("\n");
}
line++;
}
reader.close();
writeFile(DES_FILE_NAME, sw720.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public static void writeFile(String file, String text) {
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
out.println(text);
} catch (IOException e) {
e.printStackTrace();
}
out.close();
}
public static void main(String[] args) {
gen();
}
}