編輯:關於android開發
大家在Android開發時,肯定會覺得屏幕適配是個尤其痛苦的事,各種屏幕尺寸適配起來蛋疼無比。如果我們換個角度我們看下這個問題,不知道大家有沒有了解過web前端開發,或者說大家對於網頁都不陌生吧,其實適配的問題在web頁面的設計中理論上也存在,為什麼這麼說呢?電腦的顯示器的分辨率、包括手機分辨率,我敢說分辨率的種類遠超過Android設備的分辨率,那麼有一個很奇怪的現象:
為什麼Web頁面設計人員從來沒有說過,尼瑪適配好麻煩?
那麼,到底是什麼原因,讓網頁的設計可以在千差萬別的分辨率的分辨率中依舊能給用戶一個優質的體驗呢?帶著這個疑惑,我問了下媳婦(前端人員),媳婦睜大眼睛問我:什麼叫適配?fc,尼瑪,看來的確沒有這類問題。後來再我仔細的追問後,她告訴我,噢,這個尺寸呀,我都是設置為20%的~~追根到底,其實就是一個原因,網頁提供了百分比計算大小。
同樣的,大家拿到UI給的設計圖以後,是不是抱怨過尼瑪你標識的都是px,我項目裡面用dp,這什麼玩意,和UI人員解釋,UI妹妹也不理解。那麼本例同樣可以解決Android工程師和UI妹妹間的矛盾~UI給出一個固定尺寸的設計稿,然後你在編寫布局的時候不用思考,無腦照抄上面標識的像素值,就能達到完美適配,理想豐不豐滿~~。
然而,Android對於不同的屏幕給出的適配方案是dp,那麼dp與百分比的差距到底在哪裡?
我們首先看下dp的定義:
Density-independent pixel (dp)獨立像素密度。標准是160dip.即1dp對應1個pixel,計算公式如:px = dp * (dpi / 160),屏幕密度越大,1dp對應 的像素點越多。
上面的公式中有個dpi,dpi為DPI是Dots Per Inch(每英寸所打印的點數),也就是當設備的dpi為160的時候1px=1dp;
好了,上述這些概念記不記得住沒關系,只要記住一點dp是與像素無關的,在實際使用中1dp大約等於1/160inch。
那麼dp究竟解決了適配上的什麼問題?可以看出1dp = 1/160inch;那麼它至少能解決一個問題,就是你在布局文件寫某個View的寬和高為160dp*160dp,這個View在任何分辨率的屏幕中,顯示的尺寸大小是大約是一致的(可能不精確),大概是 1 inch * 1 inch。
但是,這樣並不能夠解決所有的適配問題:
呈現效果仍舊會有差異,僅僅是相近而已 當設備的物理尺寸存在差異的時候,dp就顯得無能為力了。為4.3寸屏幕准備的UI,運行在5.0寸的屏幕上,很可能在右側和下側存在大量的空白。而5.0寸的UI運行到4.3寸的設備上,很可能顯示不下。以上兩點,來自參考鏈接1
一句話,總結下,dp能夠讓同一數值在不同的分辨率展示出大致相同的尺寸大小。但是當設備的尺寸差異較大的時候,就無能為力了。適配的問題還需要我們自己去做,於是我們可能會這麼做:
<resources>
<dimen name="imagewidth">120dip
<dimen name="imagewidth">220dip
<resources>
<dimen name="imagewidth">80dip\n");
sbForWidth.append("" );
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("");
StringBuffer sbForHeight = new StringBuffer();
sbForHeight.append("\n");
sbForHeight.append("" );
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("");
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 = 400;
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 GenerateValueFiles(baseW, baseH, addition).generate();
}
}
同時我提供了jar包,默認情況下,雙擊即可生成,使用說明:
下載地址見文末,內置了常用的分辨率,默認基准為480*320,當然對於特殊需求,通過命令行指定即可:
例如:基准 1280 * 800 ,額外支持尺寸:1152 * 735;4500 * 3200;
按照
java -jar xx.jar width height width,height_width,height
上述格式即可。
到此,我們通過編寫一個工具,根據某基准尺寸,生成所有需要適配分辨率的values文件,做到了編寫布局文件時,可以參考屏幕的分辨率;在UI給出的設計圖,可以快速的按照其標識的px單位進行編寫布局。基本解決了適配的問題。
本方案思想已經有公司投入使用,個人認為還是很不錯的,如果大家有更好的方案來解決屏幕適配的問題,歡迎留言探討或者直接貼出好文鏈接,大家可以將自己的經驗進行分享,這樣才能壯大我們的隊伍~~。
更簡單更全的material design狀態欄 從實際使用需要出發,以最簡單的方式實現了幾種類型的MD狀態欄。(重點在fitsSystemWindows的使用) 0
Android Scroll詳解(一):基礎知識 Android Scroll詳解(一):基礎知識 在前邊
Android基礎入門教程——10.14 Android GPS初涉 1.定位相關的一些API 1)LocationManager 官方A
Android RecyclerView瀑布流布局添加Footer實現上拉加載 這篇文章應該是晚到了好幾個月,之前想寫,但是中途遇到了一些棘手的問題,無奈沒有去寫。寫