3、百分比的引入

1、引入

其实我们的解决方案,就是在项目中针对你所需要适配的手机屏幕的分辨率各自简历一个文件夹。

如下图:

然后我们根据一个基准,为基准的意思就是:

比如480*320的分辨率为基准

  • 宽度为320,将任何分辨率的宽度分为320份,取值为x1-x320
  • 高度为480,将任何分辨率的高度分为480份,取值为y1-y480

例如对于800*480的宽度480:

可以看到x1 = 480 / 基准 = 480 / 320 = 1.5 ;

其他分辨率类似~~ 
你可能会问,这么多文件,难道我们要手算,然后自己编写?不要怕,下文会说。

那么,你可能有个疑问,这么写有什么好处呢?

假设我现在需要在屏幕中心有个按钮,宽度和高度为我们屏幕宽度的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%; 
那么效果图:

可以看到不论在什么分辨率的机型,我们的按钮的宽和高始终是屏幕宽度的一半。

  • 对于设计图

假设现在的UI的设计图是按照480*320设计的,且上面的宽和高的标识都是px的值,你可以直接将px转化为x[1-320],y[1-480],这样写出的布局基本就可以全分辨率适配了。

你可能会问:设计师设计图的分辨率不固定怎么办?下文会说~

  • 对于上文提出的几个dp做不到的

你可以通过在引入百分比后,自己试试~~

好了,有个最主要的问题,我们没有说,就是分辨率这么多,尼玛难道我们要自己计算,然后手写?

2、自动生成工具

好了,其实这样的文件夹手写也可以,按照你们需要支持的分辨率,然后编写一套,以后一直使用。

当然了,作为程序员的我们,怎么能做这么low的工作,肯定要程序来实现:

那么实现需要以下步骤:

  1. 分析需要的支持的分辨率

对于主流的分辨率我已经集成到了我们的程序中,当然对于特殊的,你可以通过参数指定。关于屏幕分辨率信息,可以通过该网站查询:http://screensiz.es/phone

  1. 编写自动生成文件的程序

代码如下

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

Android 屏幕适配方案(转载)的更多相关文章

  1. Android 屏幕适配方案

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45460089: 本文出自:[张鸿洋的博客] 1.概述 大家在Android开发 ...

  2. 实用Android 屏幕适配方案分享

    转载地址:http://blog.csdn.net/gao_chun/article/details/45645051 真正可用,并且简单易行,可以在多个屏幕大小和屏幕密度上有良好表现的Android ...

  3. android屏幕适配方案

    曾经看了android的屏幕适配方案,有非常多种.当中自己用到的一种是:先找一款主流的分辨率的android机,如:1080*1920的分辨率做基准,然后在这个基准上.调整好一切布局.图片.适配其它手 ...

  4. Android屏幕适配方案——基于最小宽度(Smallest-width)限定符

    转自:https://www.cnblogs.com/error404/p/3815739.html 一.关于布局适配建议 1.不要使用绝对布局 2.尽量使用match_parent 而不是fill_ ...

  5. Android 屏幕适配(一)百分比布局库(percent-support-lib) 解析与扩展

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46695347: 本文出自:[张鸿洋的博客] 一.概述 周末游戏打得过猛,于是周 ...

  6. Android屏幕适配全攻略(最权威的官方适配指导)

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入 ...

  7. Android 屏幕适配:最全面的解决方案

    转自:https://www.jianshu.com/p/ec5a1a30694b 前言 Android的屏幕适配一直以来都在折磨着我们Android开发者,本文将结合: Google的官方权威适配文 ...

  8. Android屏幕适配全攻略(最权威的官方适配指导)屏幕尺寸 屏幕分辨率 屏幕像素密度 dpdipdpisppx mdpihdpixdpixxdpi

    Android屏幕适配全攻略(最权威的官方适配指导)原创赵凯强 发布于2015-05-19 11:34:17 阅读数 153734 收藏展开 转载请注明出处:http://blog.csdn.net/ ...

  9. 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

    来源:http://blog.csdn.net/zhaokaiqiang1992 更多:Android AutoLayout全新的适配方式, 堪称适配终结者 Android的屏幕适配一直以来都在折磨着 ...

随机推荐

  1. [转]Android 导入v7包常见错误,以及项目引用v7包错误解决

    android下v4    v7   v21等包是android系统的扩展支持包,就想windows的系统补丁一个道理. android的扩展包主要是用来兼容低版本的,比如android3.0以后出现 ...

  2. hrbust oj 1025 (计算几何+近似计算)

    这是我第一次只要可以这么做,题目中给的精度范围较大,所以可以把圆形的区域直接用小方块拼接近似来表示,maps地图开的越大,精度越高,但同时耗时也更多. 代码如下: #include<cstdio ...

  3. Linux学习 -- Shell编程 -- 条件判断

    按照文件类型进行判断 两种格式 test -e /root/install.log [ -e /root/install.log ]   注意空格  适合用于脚本中 echo $?可以看到结果 [ - ...

  4. Git 分支 - 分支的衍合

    分支的衍合 把一个分支中的修改整合到另一个分支的办法有两种:merge 和 rebase(译注:rebase 的翻译暂定为“衍合”,大家知道就可以了.).在本章我们会学习什么是衍合,如何使用衍合,为什 ...

  5. storm的并发

    1 storm并行的基本概念 storm集群中的一个机器可以运行一个或者多个worker,对应于一个或者多个topologies. 1个worker进程运行1个或多个excutor线程.每个worke ...

  6. 【转】PHP代码审计

    PHP代码审计 目录 1. 概述3 2. 输入验证和输出显示3 2.1 命令注入4 2.2 跨站脚本4 2.3 文件包含5 2.4 代码注入5 2.5 SQL注入6 2.6 XPath注入6 2.7 ...

  7. Ubuntu防火墙ufw安装配置

    ubuntu 系统默认已安装ufw. 1.安装sudo apt-get install ufw2.启用sudo ufw enablesudo ufw default deny运行以上两条命令后,开启了 ...

  8. tcp断开连接,4次握手,为什么wireshark 只能抓到3个包?

    用wireshark 抓包,看看tcp 断开连接的过程.  以前书上说tcp断开连接,4次握手,可我为什么wireshark 只能抓到3个包? 百度一下,别人也有类似的疑问. [求助]书上和网上的资料 ...

  9. islands打炉石传说<DP>

    islands最近在完一款游戏"炉石传说",又名"魔兽英雄传".炉石传说是一款卡牌类对战的游戏.游戏是2人对战,总的来说,里面的卡牌分成2类,一类是法术牌,另一 ...

  10. 1381: Munching(BFS)

    Description Bessie loves her grass and loves to hurry to the barn for her evening milking session. S ...