Android(安卓)屏幕适配之屏幕分辨率(创建不同dimen)适配
由于目前流行的Android屏幕分辨率太多,再加上UI同事设计时经常使用px单位来设计,所以导致编写Android代码时适配是一个很大的问题。
以下是本人开发过程中的适配方案 仅供参考
附:目前手机主流分辨率列表:http://screensiz.es/phone
屏幕适配一般原则
1.多用 match_parent
2.多用 weight+LinearLayout
3.动态获取屏幕分辨率及密度动态设置宽高(如下)
获取屏幕宽度 高度 单位px
private void getDisplayWidthHeight() { DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int width = displayMetrics.widthPixels; int height = displayMetrics.heightPixels; }
获取屏幕分辨率 160->1 240->1.5 320->2 480->3
private void getDisplayDensity() { DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); float density = displayMetrics.density; }
java代码动态设置textview高度
int h=height/10;//屏幕高度的10分之一RelativeLayout.LayoutParams pa=new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, h);textview.setLayoutParams(pa);
这样显然比较麻烦。。。
4.百分比的引入 以下是效果图
Eclipse 开发工具
Android Studio 开发工具
上图说明
即在res/文件夹下建立不同的values文件夹(高X宽(大数在前))不同的values文件夹下有相同的dimens.xml文件。相同的dimens.xml文件中有相同的名称
举例
比如480*320的分辨率为基准
宽度为320,将任何分辨率的宽度分为320份,取值为x1-x320
高度为480,将任何分辨率的高度分为480份,取值为y1-y480
即
480X320(基准)
X1->1.0px; Y1->1.0px
X2->2.0px; Y2->2.0px
X3->3.0px; Y3->3.0px
...
800X480(按比例)(高800是基准高480的1.67倍,宽1.5倍)
X1->1.5px; Y1->1.67px
X2->3.0px; Y2->3.34px
X3->4.5px; Y3->5.01px
...
其他尺寸以此类推
使用时直接按照UI同事的设计图即可,比如:一个Button 宽20px 高30px
写代码时直接 x20和y30即可。
利用工具类生成各个分辨率的文件夹
工具类代码
package wjn.com.imwithdemo.utils;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintWriter;public class GenerateValueFiles { private int baseW; private int baseH; private String dirStr = "./res"; private final static String WTemplate = "{1}px \n"; private final static String HTemplate = "{1}px \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(""); 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("<?xml version=\"1.0\" encoding=\"utf-8\"?>\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 = 720; int baseH = 1280; 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(); } }
运行此Java代码 就可以在指定文件夹下得到相应的values文件夹
将res文件夹里的所有文件拷贝到项目中res文件夹下即可
在xml文件中使用
TextView android:id="@+id/activity_main_textview" android:layout_width="@dimen/x102" android:layout_height="@dimen/y100" android:text="@string/hello_world" android:gravity="center" android:background="#FF0000" />
注意以上Java 工具类代码
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;";
此处可以添加 你自己要适配的机型。
2.代码
public static void main(String[] args) { int baseW = 720; int baseH = 1280; 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(); }
此处可以设置你的标准(一般为你的UI同时切图的基准)
注意:
本人用了一款测试机(华为P7)
手机设置中查看手机的分辨率是1080X1920 可是在写
xml布局时并没有加载values-1920x1080下相应的dimen
查阅了资料才知道 有的手机实际分辨率和设置说明的分辨率是有差距的 比如我的p7 说是 1080X1920.其实代码获取的分辨率是values-1776x1080(设置中显示的分辨率可能包括虚拟的导航栏) 希望有所帮助!!!
更多相关文章
- Android(安卓)for OpenCV 调用 CameraAPI 1 实现人脸检测
- Android(安卓)M 新的运行时权限开发者需要知道的一切
- Android技术栈(四)Android(安卓)Jetpack MVVM 完全实践
- android dialog——自定义对话框之一
- Android(安卓)Studio3.1.2 新创建项目出现build tools不匹配(以in
- 关于Android远程进程导致程序代码多次执行问题
- Android学习——windows下搭建NDK_r9环境
- Android高手进阶教程(十六)之---Android中万能的BaseAdapter(Spi
- Android使用FFmpeg 解码H264并播放(一)