-
我的首页分上下两栏,我希望每个栏目的屏幕高度为11/24,中间间隔为1/12
-
slidingmenu的宽度为屏幕宽度的80%
当然了这仅仅是从一个大的层面上来说,其实小范围布局,可能百分比将会更加有用。
那么现在不支持百分比,实现上述的需求,可能需要1、代码去动态计算(很多人直接pass了,太麻烦);2、利用weight(weight必须依赖Linearlayout,而且并不能适用于任何场景)
再比如:我的某个浮动按钮的高度和宽度希望是屏幕高度的1/12,我的某个Button的宽度希望是屏幕宽度的1/3。
上述的所有的需求,利用dp是无法完成的,我们希望控件的尺寸可以按照下列方式编写:
<Button
android:text=“@string/hello_world”
android:layout_width=“20%w”
android:layout_height=“10%h”/>
- 1
- 2
- 3
- 4
利用屏幕的宽和高的比例去定义View的宽和高。
好了,到此我们可以看到dp与百分比的区别,而百分比能够更好的解决我们的适配问题。
- some 适配tips
我们再来看看一些适配的tips
-
多用match_parent
-
多用weight
-
自定义view解决
其实上述3点tip,归根结底还是利用百分比,match_parent相当于100%参考父控件;weight即按比例分配;自定义view无非是因为里面多数尺寸是按照百分比计算的;
通过这些tips,我们更加的看出如果能在Android中引入百分比的机制,将能解决大多数的适配问题,下面我们就来看看如何能够让Android支持百分比的概念。
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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
可以看到我们的宽度和高度定义为x160,其实就是宽度的50%;
那么效果图:
可以看到不论在什么分辨率的机型,我们的按钮的宽和高始终是屏幕宽度的一半。
- 对于设计图
假设现在的UI的设计图是按照480*320设计的,且上面的宽和高的标识都是px的值,你可以直接将px转化为x[1-320],y[1-480],这样写出的布局基本就可以全分辨率适配了。
你可能会问:设计师设计图的分辨率不固定怎么办?下文会说~
- 对于上文提出的几个dp做不到的
你可以通过在引入百分比后,自己试试~~
好了,有个最主要的问题,我们没有说,就是分辨率这么多,尼玛难道我们要自己计算,然后手写?
2、自动生成工具
好了,其实这样的文件夹手写也可以,按照你们需要支持的分辨率,然后编写一套,以后一直使用。
当然了,作为程序员的我们,怎么能做这么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\n”;
private final static String HTemplate = “<dimen name=\“y{0}\”>{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}”,
总结
最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
技术进阶之路很漫长,一起共勉吧~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
[外链图片转存中…(img-QH5BTKHN-1714403392302)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
技术进阶之路很漫长,一起共勉吧~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!