由于目前流行的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("\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("\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(设置中显示的分辨率可能包括虚拟的导航栏) 希望有所帮助!!!