一、分辨率对应DPI
DPI名称=范围值 | 分辨率名称=屏幕分辨率 | density密度(1dp显示多少px) |
ldpi=120 | QVGA=240*320 | 0.75(120dpi/160=0.75px) |
mdpi=160(基线) | HVGA=320*480 | 1(160dpi/160=1px) |
hdpi=240 | WVGA=480*800 FWVGA=480*854 | 1.5(240dpi/160=1.5px) |
xhdpi=320 | 720P=720*1280 | 2(320dpi/160=2px) |
xxhdpi=480 | 1080P=1080*1920 | 3(480dpi/160=3px) |
xxxhdpi=640 | 4K=2460*3840 | 4(640dpi/160=4px) |
二、AndroidStudi目录说明
Android会根据手机屏幕分辨率选择对应文件夹中的资源,如果没有对应的文件夹,则从最高分辨率的文件夹依次往低处寻找,找到高分辨率的就压缩后显示,找到低分辨率的就放大显示。
mipmap只用来放桌面应用图标(Manifest中application标签配置的icon项),drawable用来存放图片资源,values用来针对不同分辨力编写对应资源文件。
三、品牌机型分辨率
这年头贫困户不会通过720P及以下分辨率的古董机在你APP中消费,1080P持续很多年存量极大仍是主流,1.5K是资本自以为是出的弃儿款,2K机型这几年慢慢多起来了自从有快充耗电那都不叫事。
分辨率 | 小米 | 红米 | Pixel | 三星 | OPPO | VIVO | 荣耀 | 一加 | |
720P | 720*1280 | ||||||||
720*1520 | 7/8 | ||||||||
720*1600 | 9A | ||||||||
720*1650 | 12C | ||||||||
1080P | 1080*1920 | 5/6 | 1/2 | ||||||
1080*2160 | Mix2 | 3 | |||||||
1080*2220 | 4 | ||||||||
1080*2340 | 9/10、Mix3 | 9、K20P、Note9 | 5/6/7 | S22/23 | X60 | 7 | |||
1080*2376 | X50/70 | ||||||||
1080*2400 | 12/13、Mix4 | 10、K30P/40P、Note10/11/12 | S21 | X5、Reno8 | X80、S9/10/12/15/16 | 60/70/80 | |||
1080*2412 | Reno9 | Ace1 | |||||||
1.5K | 1220*2712 | K50至尊版 | X90 | Ace2 | |||||
1240*2772 | |||||||||
1260*2800 | |||||||||
2K | 1440*2560 | ||||||||
1440*2960 | S8/9 | ||||||||
1440*3040 | S10 | ||||||||
1440*3200 | 11 | K50P/60P | S20 |
四、Java工具类
将生成的文件夹直接拖进 AndroidStudio 中的 res 中,使用的时候就 @dimen/ 后跟方向和份数。
public class DimenUtils {
private final static String rootPath = "C:/Users/Administrator/Desktop/layoutroot/values-{0}x{1}/"; //注意将Administrator替换为实际用户名
private final static float dw = 300f; //屏幕横向分为多少等份
private final static float dh = 500f; //屏幕纵向分为多少等份
private final static String WTemplate = "<dimen name=\"x{0}\">{1}px</dimen>\n"; //xml中横向条目的内容:<dimen name="x1">2.4px</dimen>
private final static String HTemplate = "<dimen name=\"y{0}\">{1}px</dimen>\n"; //xml中纵向条目的内容:<dimen name="y1">2.56px</dimen>
public static void main(String[] args) { //AndroidStudio运行失败的话选择 Run 'DimenUtils.main()' with Coverage
//720P
makeString(720, 1280);
// makeString(720, 1520);
// makeString(720, 1600);
// makeString(720, 1650);
//1080P
// makeString(1080, 1920);
// makeString(1080, 2160);
// makeString(1080, 2220);
makeString(1080, 2340);
// makeString(1080, 2376);
makeString(1080, 2400);
// makeString(1080, 2412);
//1.5K
// makeString(1220, 2712);
// makeString(1240, 2772);
// makeString(1260, 2800);
//2K
// makeString(1440, 2560);
// makeString(1440, 2960);
// makeString(1440, 3040);
makeString(1440, 3200);
}
public static void makeString(int w, int h) {
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
sb.append("<resources>");
float cellw = w / dw;
for (int i = 1; i < dw; i++) {
sb.append(WTemplate.replace("{0}", i + "").replace("{1}",
change(cellw * i) + ""));
}
sb.append(WTemplate.replace("{0}", "300").replace("{1}", w + ""));
sb.append("</resources>");
StringBuffer sb2 = new StringBuffer();
sb2.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
sb2.append("<resources>");
float cellh = h / dh;
for (int i = 1; i < dh; i++) {
sb2.append(HTemplate.replace("{0}", i + "").replace("{1}",
change(cellh * i) + ""));
}
sb2.append(HTemplate.replace("{0}", "500").replace("{1}", h + ""));
sb2.append("</resources>");
String path = rootPath.replace("{0}", h + "").replace("{1}", w + "");
File rootFile = new File(path);
if (!rootFile.exists()) {
rootFile.mkdirs();
}
File layxFile = new File(path + "lay_x.xml");
File layyFile = new File(path + "lay_y.xml");
try {
PrintWriter pw = new PrintWriter(new FileOutputStream(layxFile));
pw.print(sb.toString());
pw.close();
pw = new PrintWriter(new FileOutputStream(layyFile));
pw.print(sb2.toString());
pw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static float change(float a) {
int temp = (int) (a * 100);
return temp / 100f;
}
}
<TextView
android:layout_width="@dimen/x100"
android:layout_height="@dimen/y250"/>