我個人覺得Android適配似乎沒有完美的方案生兆,需要有一定的經(jīng)驗與技巧才能更好的適配各種分辨率問題朴乖,我覺得能夠適配百分之90以上的機(jī)型也就差不多了育灸。
其實之前一直糾結(jié)谷歌谷歌推薦我們使用dp設(shè)置view的寬高驰后,年輕時候的我一直是這么做的号坡,后來發(fā)現(xiàn)每一步手機(jī)的寬不一定是相同dp的懊烤,大部分在300到400左右 dp 吧,所以我發(fā)現(xiàn)dp不能很好的控制view在屏幕的占用比例宽堆,現(xiàn)在谷歌出了一個關(guān)于百分比的東西似乎能很好解決這個問題腌紧,但是有局限性,這里先不講畜隶,后續(xù)有空可能會補(bǔ)上寄啼。
之前看過鴻洋大神的一個不錯的適配方案(慕課網(wǎng)也有同樣的適配方案),是以某個分辨率為基準(zhǔn)代箭,將一個屏幕的寬分成320份墩划,高分為480份,以像素作為單位嗡综,生成多個分辨率的文件乙帮。這樣看基本是看不懂的,可以先屢一下思路:基于百分比的思想极景,我們可以把一個屏幕的寬分為320份察净,高同理驾茴,每個不同分辨率屏幕的320份所擁有的的像素點一般是不一樣的,所以需要在每種分辨率的文件下生成相應(yīng)的320份氢卡,看最終生成的文件比較明了:
第一個文件是默認(rèn)的锈至,新建項目就有,其他是通過代碼生成的译秦,代碼后面給出峡捡,點開values-480320和values-800480這兩個文件,看下里面如何切分320份的:
只看寬筑悴,第一個圖是480320的文件们拙,寬有320個像素,所以每一份都是一個像素阁吝,第一個圖是800480的文件砚婆,每一份有1.5個像素,都是一直分到320份的突勇。所以我們就可以用這種x1,x2,x3的方式設(shè)置view的寬装盯,大小是百分比的方式,實際上就是用像素來控制view的大小了甲馋,與谷歌所推薦的dp相違背了验夯,但是這樣能更好適配啊,看下寫個xml看下效果如何:
屏幕設(shè)置為全屏顯示的摔刁,寬高都是沒有設(shè)置滿挥转,設(shè)置成x310和y470,滿的話是x320和y480共屈,索引可以看到預(yù)覽效果都是沒有顯示滿的绑谣,這里還是沒有全屏效果,谷歌手機(jī)底部的幾個虛擬按鈕也是占用用一定像素的拗引,所以高度的顯示效果沒有體現(xiàn)出來借宵,可以看到全面8個機(jī)子顯示是能達(dá)到我們預(yù)期效果的,后面三部就完全沒有達(dá)到效果了矾削,為什么呢壤玫?因為最后三個設(shè)備的分辨率并沒有生成對應(yīng)的文件,所有者三個設(shè)備只能在values里面找x310和y470了哼凯,如果發(fā)現(xiàn)這里沒有設(shè)置這些值的話運(yùn)行可能就會報錯欲间。
<?xml version="1.0" encoding="utf-8"?>
<resources><dimen name="x1">1.0dp</dimen>
<dimen name="x2">2.0dp</dimen>
<dimen name="x3">3.0dp</dimen>
<dimen name="x4">4.0dp</dimen>
上面只是復(fù)制了一部分values/lay_x.xml里面的值,這里面的值就是當(dāng)某個分辨率的手機(jī)找不到自己對應(yīng)的文件時就會來這里找断部,這里的寫法我寫的比較特別猎贴,x1代表1dp,x320代表320dp,所以前面那張圖的后三個設(shè)備就是以dp來控制view的大小的
總的來說這個適配方法還是不錯的她渴,但是要考慮到過多的分辨率达址,一旦沒考慮到的分辨率,該機(jī)型的適配就跟其他機(jī)型顯示效果不一樣了趁耗。最后想問下哪位大哥如果有更好的適配方案可以共享呢沉唠?
后面給出生成各種分辨率的代碼吧
public class MakeXml {
private int baseW;
private int baseH;
private String dirStr = "./res";
private final static String WTemplate = "<dimen name=\"x{0}\">{1}px</dimen>\n";
private final static String HTemplate = "<dimen name=\"y{0}\">{1}px</dimen>\n";
/**
* {0}-HEIGHT
*/
private final static String VALUE_TEMPLATE = "values-{0}x{1}";
private static final String SUPPORT_DIMESION =
"320,480;" +
"480,800;" +
"480,854;" +
"540,960;" +
"600,1024;" +
"720,1184;" +
"720,1196;" +
"720,1280;" +
"768,1280;" +
"768,1024;" +
"800,1280;" +
"1080,1812;" +
"1080,1920;" +
"1440,2560;";
private String supportStr = SUPPORT_DIMESION;
public MakeXml(int baseX, int baseY, String supportStr) {
this.baseW = baseX;
this.baseH = baseY;
if (!this.supportStr.contains(baseX + "," + baseY)) {
this.supportStr += baseX + "," + baseY + ";";
}
this.supportStr += validateInput(supportStr);
System.out.println(supportStr);
File dir = new File(dirStr);
if (!dir.exists()) {
dir.mkdir();
}
System.out.println(dir.getAbsoluteFile());
}
/**
* @param supportStr w,h_...w,h;
* @return
*/
private String validateInput(String supportStr) {
StringBuffer sb = new StringBuffer();
String[] vals = supportStr.split("_");
int w = -1;
int h = -1;
String[] wh;
for (String val : vals) {
try {
if (val == null || val.trim().length() == 0)
continue;
wh = val.split(",");
w = Integer.parseInt(wh[0]);
h = Integer.parseInt(wh[1]);
} catch (Exception e) {
System.out.println("skip invalidate params : w,h = " + val);
continue;
}
sb.append(w + "," + h + ";");
}
return sb.toString();
}
public void generate() {
String[] vals = supportStr.split(";");
for (String val : vals) {
String[] wh = val.split(",");
generateXmlFile(Integer.parseInt(wh[0]), Integer.parseInt(wh[1]));
}
}
private void generateXmlFile(int w, int h) {
StringBuffer sbForWidth = new StringBuffer();
sbForWidth.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
sbForWidth.append("<resources>");
float cellw = w * 1.0f / baseW;
System.out.println("width : " + w + "," + baseW + "," + cellw);
for (int i = 1; i < baseW; i++) {
sbForWidth.append(WTemplate.replace("{0}", i + "").replace("{1}",
change(cellw * i) + ""));
}
sbForWidth.append(WTemplate.replace("{0}", baseW + "").replace("{1}",
w + ""));
sbForWidth.append("</resources>");
StringBuffer sbForHeight = new StringBuffer();
sbForHeight.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
sbForHeight.append("<resources>");
float cellh = h * 1.0f / baseH;
System.out.println("height : " + h + "," + baseH + "," + cellh);
for (int i = 1; i < baseH; i++) {
sbForHeight.append(HTemplate.replace("{0}", i + "").replace("{1}",
change(cellh * i) + ""));
}
sbForHeight.append(HTemplate.replace("{0}", baseH + "").replace("{1}",
h + ""));
sbForHeight.append("</resources>");
File fileDir = new File(dirStr + File.separator
+ VALUE_TEMPLATE.replace("{0}", h + "")//
.replace("{1}", w + ""));
fileDir.mkdir();
File layxFile = new File(fileDir.getAbsolutePath(), "lay_x.xml");
File layyFile = new File(fileDir.getAbsolutePath(), "lay_y.xml");
try {
PrintWriter pw = new PrintWriter(new FileOutputStream(layxFile));
pw.print(sbForWidth.toString());
pw.close();
pw = new PrintWriter(new FileOutputStream(layyFile));
pw.print(sbForHeight.toString());
pw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static float change(float a) {
int temp = (int) (a * 100);
return temp / 100f;
}
public static void main(String[] args) {
int baseW = 320;
int baseH = 480;
String addition = "";
try {
if (args.length >= 3) {
baseW = Integer.parseInt(args[0]);
baseH = Integer.parseInt(args[1]);
addition = args[2];
} else if (args.length >= 2) {
baseW = Integer.parseInt(args[0]);
baseH = Integer.parseInt(args[1]);
} else if (args.length >= 1) {
addition = args[0];
}
} catch (NumberFormatException e) {
System.err
.println("right input params : java -jar xxx.jar width height w,h_w,h_..._w,h;");
e.printStackTrace();
System.exit(-1);
}
new MakeXml(baseW, baseH, addition).generate();
}
}