android 创建多个dimens文件的作用
2016-04-07 09:08
495 查看
巧用dimens适配多个分辨率
作者:望月听涛发布:2013-02-2711:16分类:阅读:3,034次
如:
values-320x240下的dimens文件只有在分辨率是320X240的时候才起作用 values-960x720下的dimens文件只有在分辨率是960x720的时候才起作用 如果不是这两个分辨率的手机就调用的是vales下面的dimens
dimens文件一般是定义一个尺寸,以便于复用,dimes文件不能起作用,很有可能是因为xml文件多了这样一句代码:<?xmlversion="1.0"encoding="utf-8"?>,删掉即可。
如果手机分辨率不符合所在的文件夹的分辨率,系统会自动去适配最接近的尺寸。出现上述问题是否是代码当中存在错误。
摘自:http://blog.csdn.net/ocean20/article/details/23353663
让应用自动适配多个分辨率的屏幕,是每个android程序员的基本功,就好像前端工程师熟练编写CSSHack一样。适配工作中一个重要的工作就是对页面的调整。
对于页面的适配,有很多的方法和技巧。比如布局中尽量使用wrapcontent,fillparent,尽量避免具体的数字,由系统来计算合适的宽高;或者为每个分辨率写一套布局文件,设置对应分辨率下控件的宽高;
为每一个分辨率写一套布局文件虽然够独立,够简单。但是维护起来成本较高。一个页面的改动,往往涉及多个布局文件的改动,让人很痛苦。
小技巧
我们可以尝试只写一套xml布局,然后为该布局准备多套dimension文件。说的详细一点就是,xml布局中组件的宽高,不要使用具体的数值来表示,而是配置到dimension文件中。每套dimension文件中数值的大小都是成比例计算出来。
比如在1980*1080分辨率下,定义px15表示15px
<dimenname="px15">15px</dimen>
那么在1080*720分辨率下,px15要成比例缩小1.5倍,定义px15表示10px
<dimenname="px15">10px</dimen>
所以在xml布局文件中,我们可以这样来表示:
<LinearLayout
android:layout_width="@dimen/px150"
android:layout_height="@dimen/px15"
android:orientation="vertical">
……
……
</LinearLayout>
这套布局文件中的LinearLayout在1980*1080分辨率下的宽高为150x15,在1080*720分辨率下的宽高就会自动变成100*10
其他分辨率同理
疑问
1.有的同学会疑问,这样不就变成需要维护多套dimenson文件了?换汤不换药呀?其实不然,对于dimension文件我们可以使用代码来控制生成,数值范围可以根据自己的情况来。其他分辨率下只需要按照相应比例,使用代码算一下即可。
编写一个这样的生成代码并不难,下篇文章我们再给出。
生成完毕后,Values目录结构如下:
2.按比例计算布局一定可靠吗,会不会出现混乱的现象
有可能会,这个时候就需要协调布局使用的宽高,选择合适的宽高让页面在各个分辨率下,看起来不算离谱就行,不一定严格按照设计来。大部分页面是兼容的。
以上介绍了使用dimension文件做适配。说道了使用代码自动生成所有的dimension文件,接下来我们给出相关代码。
DimensTools:
packagecom.example.test;
importjava.io.*;
importjava.util.*;
/**
*dimens数据自动生成工具
*
*/
publicclassDimensTools{
/**源文件*/
staticStringoldFilePath="./res/values-nodpi/dimens.xml";
/**新生成文件路径*/
staticStringfilePath720="./res/values-1280x720/dimens.xml";
/**新生成文件路径*/
staticStringfilePath672="./res/values-1280x672/dimens.xml";
/**新生成文件路径*/
staticStringfilePath1080="./res/values-1920x1080/dimens.xml";
/**缩小倍数*/
staticfloatchanges=1.5f;
publicstaticvoidmain(String[]args){
//生成1-1920px
StringallPx=getAllPx();
DeleteFolder(oldFilePath);
writeFile(oldFilePath,allPx);
Stringst=convertStreamToString(oldFilePath,changes);
DeleteFolder(filePath720);
writeFile(filePath720,st);
DeleteFolder(filePath672);
writeFile(filePath672,st);
Stringst1=convertStreamToString(oldFilePath,1f);
DeleteFolder(filePath1080);
writeFile(filePath1080,st1);
}
/**读取文件生成缩放后字符串*/
publicstaticStringconvertStreamToString(Stringfilepath,floatf){
StringBuildersb=newStringBuilder();
try{
BufferedReaderbf=newBufferedReader(newFileReader(filepath));
Stringline=null;
System.out.println("q1");
Stringendmark="px</dimen>";
Stringstartmark=">";
while((line=bf.readLine())!=null){
if(line.contains(endmark)){
intend=line.lastIndexOf(endmark);
intstart=line.indexOf(startmark);
Stringstpx=line.substring(start+1,end);
intpx=Integer.parseInt(stpx);
intnewpx=(int)((float)px/f);
Stringnewline=line.replace(px+"px",newpx+"px");
sb.append(newline+"\r\n");
}else{
sb.append(line+"\r\n");
}
}
System.out.println(sb.toString());
}catch(IOExceptione){
e.printStackTrace();
}
returnsb.toString();
}
/**
*根据路径删除指定的目录或文件,无论存在与否
*
*@paramsPath
*要删除的目录或文件
*@return删除成功返回true,否则返回false。
*/
publicstaticbooleanDeleteFolder(StringsPath){
Filefile=newFile(sPath);
////判断目录或文件是否存在
if(!file.exists()){//不存在返回false
returntrue;
}else{
//判断是否为文件
if(file.isFile()){//为文件时调用删除文件方法
returndeleteFile(sPath);
}else{//为目录时调用删除目录方法
//returndeleteDirectory(sPath);
}
}
returnfalse;
}
/**存为新文件*/
publicstaticvoidwriteFile(Stringfilepath,Stringst){
try{
FileWriterfw=newFileWriter(filepath);
BufferedWriterbw=newBufferedWriter(fw);
bw.write(st);
bw.flush();
bw.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
/**生成全px文件*/
publicstaticStringgetAllPx(){
StringBuildersb=newStringBuilder();
try{
sb.append("<resources>"+"\r\n");
sb.append("<dimenname=\"screen_width\">1920px</dimen>"+"\r\n");
sb.append("<dimenname=\"screen_height\">1080px</dimen>"+"\r\n");
for(inti=1;i<=1920;i++){
System.out.println("i="+i);
sb.append("<dimenname=\"px"+i+"\">"+i+"px</dimen>"
+"\r\n");
}
sb.append("</resources>"+"\r\n");
System.out.println(sb.toString());
}catch(Exceptione){
e.printStackTrace();
}
returnsb.toString();
}
/**
*删除单个文件
*
*@paramsPath
*被删除文件的文件名
*@return单个文件删除成功返回true,否则返回false
*/
publicstaticbooleandeleteFile(StringsPath){
booleanflag=false;
Filefile=newFile(sPath);
//路径为文件且不为空则进行删除
if(file.isFile()&&file.exists()){
file.delete();
flag=true;
}
returnflag;
}
}
使用方法:cmd下使用javac,java命令运行。这样有点费劲哈,改天用ant写个自动脚本放上来。
注:先建立好相应的文件夹,672也按照1.5的比例缩放的。可以根据自己的需要调整。
相关文章推荐
- ViewHolder工具类【收藏】
- android蓝牙扫描(scan)设备分析
- Android内存优化十一:Android之安全机制
- Android 6.0 Marshmallow tips and tricks 棉花糖的技巧和窍门
- Android内存优化十:Android内存管理机制详解
- 对android应用程序的理解
- Android 5.0鲜为人知的新特性
- android获取相册图片和路径的实现方法
- 使用meminfo分析Android单个进程内存信息
- Android lbs位置服务
- Android属性动画
- ANDROID——仿360手机卫士的旋转打分控件
- ANDROID——仿360手机卫士的旋转打分控件
- ANDROID——仿360手机卫士的旋转打分控件
- Android Binder总结
- android studio 混淆后,打包报错!!!
- cmandroid系统编译
- 关于android系统编译
- Android开发 图片轮播条Lanner(可无限滚动循环,自定义dots样式位置,延迟时间,滚动时间,点击事件)
- Android Studio使用记录