屏幕适配
来源:互联网 发布:linux 修改文件权限 编辑:程序博客网 时间:2024/06/05 09:53
一些关于屏幕的概念:
px
像素, 即 屏幕上最小的点 可以显示一个颜色值
inch
英寸, 外国单位,1英寸=2.54厘米
分辨率
宽高所拥有的像素值 720*1280 宽为720个像素 高位1280个px
ppi
pixels per inch : 每英寸的像素点 通常我们是算的屏幕对角线的
ppi=(斜对角线的像素个数)/(斜对角线长度 单位为英寸) 即ppi=√(分辨率高的平方+分辨率宽的平方)/√(屏幕长度的平方+屏幕宽度的平方)其实就是用勾股定理算出对角线的像素个数和对角线的长度 相除 比如以720*1280 4.7寸屏为例(4.7寸屏就是指斜对角线长度) 即 ppi=√(1280^2+720^2)/4.7=312.469Dpi跟ppi是一个概念 意思是屏幕密度 数字越大 表示一英寸里容纳了越多的像素点,屏幕看起来就越精细
这里 对android 对ppi的大小设置了几个级别
DENSITY_LOW = 120 DENSITY_MEDIUM = 160 //默认值 DENSITY_HIGH = 240 //高清DENSITY_XHIGH = 320 //超清DENSITY_XXHIGH = 480 DENSITY_XXXHIGH = 640
超过某个值 就大概在哪个级别,比如刚才算出来的312.469 其实就在hdpi与xhdpi之间. 差不多就是xhdpi 商家是肯定会这么号称:超清屏
android设备比较乱 所以跟标准值一样的很少
另外
同一个ppi下,分辨率越大就越清晰
同一个ppi下,屏幕越大就越模糊 大电视上的颜色块我们应该都见过.
我就遇到过一个奇葩手机,他的屏幕跟其他手机一样大, 但是分辨率很低, 结果就造成了 手机看上去跟其他手机一样,价格都差不多,然后显示就是比别人的粗糙 显示的控件就是比别人的大
接下来轮到dp了
dp
dp是一种我们计算出来的单位 , 它在不同ppi上表示的像素个数不同,具体换算公式如下:
px=dp*(实际ppi/160)
在上面分出的等级里 我们把 ppi=160 定义为标准屏幕密度(几年前的标注 那时普遍ppi都低)
dp的作用是:为了在不同屏幕手机上显示出一样的大小
问题的出现:
320像素
在ppi160屏幕上显示的是2(320/160)英寸
在ppi 320的屏幕上 就只有1(320/320)英寸了
在ppi 640的屏幕上 只有0.5(320/640)英寸
越清晰就显示得越小,在低分屏还能看清 到了高分屏上就难说了,所以我们用px作为单位 就很不合适了 因为不能随屏幕变化而变化
由此引进dp这个单位,对px和ppi进行统一
其实就是根据比例缩放
像素不是在高分屏上缩小了么 那么缩小多少 我就乘以多少,
比如上面的
320像素 在 ppi160屏幕上显示的是2英寸
到ppi320 1英寸要显示为2英寸 那么就乘以2
到ppi640 0.5英寸要显示为2英寸 那么就乘以4
dp就是这里的比例关系
dp=px*160/ppi
也就是说
dp是为了保证在不同屏幕手机上显示出一样物理的大小
google这个设置 大致解决了分辨率的问题 保证了你在这个手机上设置的东西在另一台手机上都能看清.但新的问题来了 我们上面看到的是这个效果
但是一般来说,高ppi手机屏幕实际上就比低的大,
有两台手机配置如下:
4.0英寸–800x480–233ppi
5.0英寸–1920x1080–441ppi
你按第一台手机上写了控件高度549dp(549*233/160=800),也就是整个屏幕,结果到了5.0英寸的手机上549dp占多长呢
549*441/160=1513px
也就是说在4.0手机上显示的全屏的控件 在5.0手机上只有78%(1513/1920),还有一部分是空余.
再说我们实际要求吧 其实我们想要的效果是显示比例相同
如图:
一个控件在小手机上显示占50% 那么 我想要在大屏幕上也显示占50%
相信大部分人都看过这样的文件夹
各种value 里面的dimen 配置不同的比例dp
这里用到了屏幕等分,让一个东西在所有手机上看起来比例都一样,我们把屏幕高等分成320(份数自己定 保证够细)份 然后计算出不同屏幕上 每一份对应的dp的值
比如
在800x480分辨率ppi233的屏幕上,将高分成320份,创建320个dimen值
dp=px*160/实际ppi=800*160/233=549.35
800px换成ppi下的dp就是549.35dp
dp与每一等份的关系如下
dimen_y_1=549.35 *1/320=1.716dp dimen_y_2=549.35 *2/320=3.433dpdimen_y_3=549.35 *3/320=4.609dp.........dimen_y_320=549.35 *320/320=549.35dp
在720*1280分辨率ppi312屏幕上 同样也是分成320份 属性值和上面一样
dp=px*160/ppi=1280*160/312=656.41
1280px换成ppi下的dp就是656.41dp 将 656.41dp平均分成320份
dimen_y_1=2.05dp dimen_y_2=4.10dpdimen_y_3=6.15dp.........dimen_320=656.41dp
这是设置高, 我们再设置宽的时候也加这个属性
dimen_x_1=XXXdp
这样我们设置的时候用我们自己的单位
android:layout_width=”@dimen/dimen_x_320”
android:layout_width=”@dimen/dimen_y_32”
如此 :
宽为全屏
高位10%
当然 分辨率太多不会要你自己一个个算,网上有写好的生成这些文件的脚本执行下就行了,代码如下:
import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintWriter;public class MakeXml { private final static String rootPath = "D:\\layoutroot\\values-{0}x{1}\\"; private final static float dw = 320f; private final static float dh = 480f; 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"; public static void main(String[] args) { makeString(320, 480); makeString(480,800); makeString(480, 854); makeString(540, 960); makeString(600, 1024); makeString(720, 1184); makeString(720, 1196); makeString(720, 1280); makeString(768, 1024); makeString(800, 1280); makeString(1080, 1812); makeString(1080, 1920); makeString(1440, 2560); } 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 < 320; i++) { sb.append(WTemplate.replace("{0}", i + "").replace("{1}", change(cellw * i) + "")); } sb.append(WTemplate.replace("{0}", "320").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 < 480; i++) { sb2.append(HTemplate.replace("{0}", i + "").replace("{1}", change(cellh * i) + "")); } sb2.append(HTemplate.replace("{0}", "480").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; }}
- 【Android 屏幕适配】 屏幕适配
- Android 屏幕适配--屏幕旋转
- COCOS2DX屏幕显示与屏幕适配
- Android屏幕适配-----屏幕尺寸
- Android屏幕尺寸单位/屏幕适配
- 屏幕适配
- 【Android】屏幕适配
- android屏幕适配
- android屏幕适配
- android 屏幕适配
- Android屏幕适配
- Android屏幕适配
- Android屏幕适配
- Android屏幕适配
- android 屏幕适配
- 屏幕适配
- Android屏幕适配
- Android屏幕适配
- 面试笔试整理4:机器学习面试问题准备(进阶)
- linux消息队列
- PDF文件如何进行编辑、使用什么PDF编辑器好?
- |9.6|下午
- GraphX和GraphFrame connectedComponent计算性能对比
- 屏幕适配
- MySQL索引背后的数据结构及算法原理
- Asp.Net WebAPI中Filter过滤器的使用以及执行顺序
- 令牌的生成和验证工具类
- PAT (Basic Level) Practise (中文) 1036. 跟奥巴马一起编程(15)
- 数据库的范式(1NF、2NF、3NF、BNCF)
- Android系统目录结构
- node.js后台快速搭建在阿里云(二)(pm2和nginx篇)
- 关于JUnit 的笔记