UI给的切图是1280x720这个分辨率的,给的标注单位是px(像素)。把图片放在drawable-xhdpi中,然后开始调整布局(当时默认1dp=2px)。把这个布局放到一个720P的电视上,发现完全变形了,看了下电视的density,发现这货是1,这是一个mdpi的设备!
然后我就开始想了,720P的切图,要放在xhdpi这里,但是有的设备自身是mdpi之类的,那这个分辨率和dpi到底是什么关系?
我们先来了解下分辨率和像素:
DPI:每英寸像素数
简单的屏幕分辨率计算方法:
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
float density = metrics.density;
int dpi = metrics.densityDpi;
int heightPixels = metrics.heightPixels;
int widthPixels = metrics.widthPixels;
---metrics---", "比例:"+density+",dpi:"+dpi+",高像素:"+heightPixels+",宽像素:"+widthPixels);
这个屏幕高度是不包含虚拟按键的高度,如果要带上虚拟按键的总高度可以这样
/**
* 通过反射,获取包含虚拟键的整体屏幕高度
*
* @return
*/
private int getHasVirtualKey() {
int height = 0;
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, dm);
height = dm.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return height;
}
最小屏幕宽度:160*屏幕宽度像素/dpi
名称 | dpi | 屏幕密度 | 图片icon尺寸 |
drawable-ldpi | 120 | density=0.75 | 36*36 |
drawable-mdpi | 160 | density=1(baseline) | 48*48 |
drawable-hdpi | 240 | density=1.5 | 72*72 |
drawable-xhdpi | 320 | density=2 | 96*96 |
drawable-xxhdpi | 480 | density=3 | 144*144 |
drawable-xxxhdpi | 640 | density=4 | 192*192 |
注:Android studio mipmap文件夹只存放启动图标icon
1.为什么一个720P的设备,取mdpi里的图片,但是720P的切图要放在xhdpi里?
A: 这完全是根据主流手机来决定的,比如现在主流的是480P/hdpi的手机,那么,在做UI时,就会取720P作为xhdpi,取320P作为mdpi,取240P作为ldpi,这样一套套图就切出来了。
如果,主流的手机分辨率变成了720P/hdpi的手机,那么,在做UI时,就会取480P作为mdpi,取1080P作为xhdpi,以此类推。
至于Google是这样推荐的:取你手边最大的分辨率作为基准,做出最清晰的图(xhdpi),然后,按比例缩放,做出hdpi、mdpi和ldpi。所以从原理上,720P的切图放在哪里是可以根据设备来变换的。
2.如果720P的切图在xhdpi里,但我手头有一个mdpi/720P的设备,那怎么办呢?
(假设你的应用要支持所有奇葩的分辨率,而且你已经切好了4套图(ldpi~xhdpi) 并在layout里写了一套布局)
A: 如果你自己思考了dpi和分辨率的关系的话,你会发现,他们的关系就是没有关系...所以这个问题,我的解决办法(大家的)是,让多套dimens来帮我们解决这个问题。
| 480p | 600p | 720p | 1080p |
mdpi | values-sw480dp-mdpi | values-sw600dp-mdpi | values-sw720dp-mdpi | values-sw1080dp-mdpi |
hdpi | values-sw480dp-hdpi | … | … | … |
xhdpi | values-sw480dp-xhdpi | … | … | … |
在你的res文件夹下,新建这些文件夹,然后再放进一个dimens.xml,用这种方法,就可以应对所有的分辨率情况了。
举例说明下:如果原图(1280x720)上有一个100x50(像素)大小的控件,那么对于一个正常的hdpi/800x480的设备来说,应该设置它的大小(dp)为:
长:(100/720*480/1.5)dp = 45dp (向上取整)
宽:(50/720*480/1.5)dp = 23dp
将这两个值写在values-sw480dp-hdpi/dimens.xml里,图的比例和原图就一样了。
那对于一个刚才我列举到的mdpi/1280x720的设备,它的大小应该是:
长:(100/720*720/1) = 100dp;
宽:(50/720*720/1) = 50dp;
将这两个值写在values-sw720dp-mdpi中,图的比例和原图就一样了。
还有个大佬写的自适应屏幕的东西,不过已经停止维护了
GitHub地址:https://github.com/hongyangAndroid/AndroidAutoLayout
这是关于计算手机最小宽度(以dp为单位)
最近在开发中遇到屏幕适配的问题:都是使用dp为单位,出来的效果却不一样。
对比手机:
两个手机屏幕尺寸相同,都是5.7英寸,同样画100dp的线,在屏幕上的长度却不一样,Note5上显示的要短一些。
原因为两个手机最小宽度(以dp为单位)不同。
怎样计算
安卓根据手机ppi设置dpi,分为 120(ldpi)、160(mdpi)、213、240(hdpi)、280、320(xhdpi)、360、400、420、480(xxhdpi)、560、640(xxxhdpi);
根据DisplayMetrics可以获取到手机dpi,Note5比较特殊为560(ppi为515),A8为480(ppi为386)。
所以
Note5 dp=160*1440/560=411
A8 dp=160*1080/480=360
怎样解决
安卓会自动根据手机的大小(按宽度算 dp为单位)去选择values或者values-swxxxdp。
sw为small width,后面接的值表示,屏幕的最小宽度dp大于这个值的时候启用。
所以写了两个dimens.xml分别放在
res/values/dimens.xml
res/values-sw400dp/dimens.xml
Note5会找values-sw400dp/dimens.xml,A8会找默认的values/dimens.xml;
默认的总宽度为360dp,放在values/dimens.xml文件中:
<resources>
<dimen name="DIMEN_1dp">1dp</dimen>
<dimen name="DIMEN_2dp">2dp</dimen>
<dimen name="DIMEN_3dp">3dp</dimen>
<dimen name="DIMEN_5dp">5dp</dimen>
<dimen name="DIMEN_6dp">6dp</dimen>
<dimen name="DIMEN_7dp">7dp</dimen>
<dimen name="DIMEN_8dp">8dp</dimen>
<dimen name="DIMEN_10dp">10dp</dimen>
<dimen name="DIMEN_11dp">11dp</dimen>
<dimen name="DIMEN_12dp">12dp</dimen>
<dimen name="DIMEN_13dp">13dp</dimen>
<dimen name="DIMEN_14dp">14dp</dimen>
<dimen name="DIMEN_15dp">15dp</dimen>
<dimen name="DIMEN_16dp">16dp</dimen>
<dimen name="DIMEN_18dp">18dp</dimen>
<dimen name="DIMEN_20dp">20dp</dimen>
<dimen name="DIMEN_22dp">22dp</dimen>
<dimen name="DIMEN_24dp">24dp</dimen>
<dimen name="DIMEN_26dp">26dp</dimen>
<dimen name="DIMEN_30dp">30dp</dimen>
<dimen name="DIMEN_32dp">32dp</dimen>
<dimen name="DIMEN_36dp">36dp</dimen>
<dimen name="DIMEN_40dp">40dp</dimen>
<dimen name="DIMEN_42dp">42dp</dimen>
<dimen name="DIMEN_45dp">45dp</dimen>
<dimen name="DIMEN_46dp">46dp</dimen>
<dimen name="DIMEN_50dp">50dp</dimen>
<dimen name="DIMEN_52dp">52dp</dimen>
<dimen name="DIMEN_60dp">60dp</dimen>
<dimen name="DIMEN_65dp">65dp</dimen>
<dimen name="DIMEN_70dp">70dp</dimen>
<dimen name="DIMEN_80dp">80dp</dimen>
<dimen name="DIMEN_90dp">90dp</dimen>
<dimen name="DIMEN_100dp">100dp</dimen>
<dimen name="DIMEN_120dp">120dp</dimen>
<dimen name="DIMEN_130dp">130dp</dimen>
<dimen name="DIMEN_150dp">150dp</dimen>
<dimen name="DIMEN_190dp">190dp</dimen>
<dimen name="DIMEN_200dp">200dp</dimen>
<dimen name="DIMEN_240dp">240dp</dimen>
<dimen name="DIMEN_250dp">250dp</dimen>
<dimen name="DIMEN_255dp">255dp</dimen>
<dimen name="DIMEN_300dp">300dp</dimen>
</resources>
411dp的宽度呢?由于411和360是1.14倍的关系,所以 DIMEN_1dp = 1.14dp
<resources>
<!-- 这里用的1.2,应该是1.14 -->
<dimen name="DIMEN_1dp">1.2dp</dimen>
<dimen name="DIMEN_2dp">2.4dp</dimen>
<dimen name="DIMEN_3dp">4.8dp</dimen>
<dimen name="DIMEN_5dp">6dp</dimen>
<dimen name="DIMEN_6dp">7.2dp</dimen>
<dimen name="DIMEN_7dp">8.4dp</dimen>
<dimen name="DIMEN_8dp">9.6dp</dimen>
<dimen name="DIMEN_10dp">12dp</dimen>
<dimen name="DIMEN_11dp">13.2dp</dimen>
<dimen name="DIMEN_12dp">14.4dp</dimen>
<dimen name="DIMEN_13dp">15.6dp</dimen>
<dimen name="DIMEN_14dp">16.8dp</dimen>
<dimen name="DIMEN_15dp">18dp</dimen>
<dimen name="DIMEN_16dp">19.2dp</dimen>
<dimen name="DIMEN_18dp">21.6dp</dimen>
<dimen name="DIMEN_20dp">24dp</dimen>
<dimen name="DIMEN_22dp">26.4dp</dimen>
<dimen name="DIMEN_24dp">28.8dp</dimen>
<dimen name="DIMEN_26dp">31.2dp</dimen>
<dimen name="DIMEN_30dp">36dp</dimen>
<dimen name="DIMEN_32dp">38.4dp</dimen>
<dimen name="DIMEN_36dp">43.2dp</dimen>
<dimen name="DIMEN_40dp">48dp</dimen>
<dimen name="DIMEN_42dp">50.4dp</dimen>
<dimen name="DIMEN_45dp">54dp</dimen>
<dimen name="DIMEN_46dp">55.2dp</dimen>
<dimen name="DIMEN_50dp">60dp</dimen>
<dimen name="DIMEN_52dp">62.4dp</dimen>
<dimen name="DIMEN_60dp">72dp</dimen>
<dimen name="DIMEN_65dp">78dp</dimen>
<dimen name="DIMEN_70dp">84dp</dimen>
<dimen name="DIMEN_80dp">96dp</dimen>
<dimen name="DIMEN_90dp">108dp</dimen>
<dimen name="DIMEN_100dp">120dp</dimen>
<dimen name="DIMEN_120dp">144dp</dimen>
<dimen name="DIMEN_130dp">156dp</dimen>
<dimen name="DIMEN_150dp">180dp</dimen>
<dimen name="DIMEN_190dp">228dp</dimen>
<dimen name="DIMEN_200dp">240dp</dimen>
<dimen name="DIMEN_240dp">288dp</dimen>
<dimen name="DIMEN_250dp">300dp</dimen>
<dimen name="DIMEN_255dp">306dp</dimen>
<dimen name="DIMEN_300dp">360dp</dimen>
</resources>