其實咱們的解決方案,就是在項目中針對你所須要適配的手機屏幕的分辨率各自簡歷一個文件夾。java
以下圖:android
而後咱們根據一個基準,爲基準的意思就是:git
好比480*320的分辨率爲基準程序員
例如對於800*480的寬度480:github
能夠看到x1 = 480 / 基準 = 480 / 320 = 1.5 ;app
其餘分辨率相似~~
你可能會問,這麼多文件,難道咱們要手算,而後本身編寫?不要怕,下文會說。工具
那麼,你可能有個疑問,這麼寫有什麼好處呢?佈局
假設我如今須要在屏幕中心有個按鈕,寬度和高度爲咱們屏幕寬度的1/2,我能夠怎麼編寫佈局文件呢?網站
<FrameLayout > <Button android:layout_gravity="center" android:gravity="center" android:text="@string/hello_world" android:layout_width="@dimen/x160" android:layout_height="@dimen/x160"/> </FrameLayout>
能夠看到咱們的寬度和高度定義爲x160,其實就是寬度的50%;
那麼效果圖:this
能夠看到不論在什麼分辨率的機型,咱們的按鈕的寬和高始終是屏幕寬度的一半。
假設如今的UI的設計圖是按照480*320設計的,且上面的寬和高的標識都是px的值,你能夠直接將px轉化爲x[1-320],y[1-480],這樣寫出的佈局基本就能夠全分辨率適配了。
你可能會問:設計師設計圖的分辨率不固定怎麼辦?下文會說~
你能夠經過在引入百分比後,本身試試~~
好了,有個最主要的問題,咱們沒有說,就是分辨率這麼多,尼瑪難道咱們要本身計算,而後手寫?
好了,其實這樣的文件夾手寫也能夠,按照大家須要支持的分辨率,而後編寫一套,之後一直使用。
固然了,做爲程序員的咱們,怎麼能作這麼low的工做,確定要程序來實現:
那麼實現須要如下步驟:
對於主流的分辨率我已經集成到了咱們的程序中,固然對於特殊的,你能夠經過參數指定。關於屏幕分辨率信息,能夠經過該網站查詢:http://screensiz.es/phone
代碼以下
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter; /** * Created by zhy on 15/5/3. */ public class GenerateValueFiles { 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,1024;800,1280;1080,1812;1080,1920;1440,2560;"; private String supportStr = SUPPORT_DIMESION; public GenerateValueFiles(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 = 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
上述格式便可。
java -jar autolayout.jar 640 1136 320,480_480,800_480,854_540,960_600,1024_768,1024_720,1184_720,1196_720,1280_800,1280_1080,1812_1080,1920_1440,2560
到此,咱們經過編寫一個工具,根據某基準尺寸,生成全部須要適配分辨率的values文件,作到了編寫佈局文件時,能夠參考屏幕的分辨率;在UI給出的設計圖,能夠快速的按照其標識的px單位進行編寫佈局。基本解決了適配的問題。
下載地址:https://github.com/hongyangAndroid/Android_Blog_Demos/tree/master/blogcodes/src/main/java/com/zhy/blogcodes/genvalues
===>後期更新
Google已經添加了百分比支持庫,詳情請看:Android 百分比佈局庫(percent-support-lib) 解析與擴展
ok~
轉載來自:http://blog.csdn.net/lmj623565791/article/details/45460089