Android Drawable
一个Android项目有很多drawable文件夹,分别对应不同的dpi
- drawable-ldpi (dpi=120, density=0.75)
- drawable-mdpi (dpi=160, density=1)
- drawable-hdpi (dpi=240, density=1.5)
- drawable-xhdpi (dpi=320, density=2)
- drawable-xxhdpi (dpi=480, density=3)
Android SDK会自动屏幕尺寸选择对应的资源文件进行渲染,如SDK检测到你手机dpi是160的话会优先到drawable-mdpi文件夹下找对应的图片资源,注意只是优先,假设你手机dpi是160,但是你只在xhpdi文件夹下有对应的图片资源文件,程序一样可以正常运行。所以理论上来说只需要提供一种规格的图片资源就ok了,如果只提供ldpi规格的图片,对于大分辨率的手机如果把图片放大就会不清晰,所以需要提供一套你需要支持的最大dpi的图片,这样即使用户的手机分辨率很小,这样图片缩小依然很清晰。
xhdpi
目前市面上最普遍的高端机的分辨率还多集中在720X1080范围,也就是多集中在xhdpi,所以目前来看xhpdi规格的图片成为了首选。
利用IOS设计资源
iPhone5的屏幕分辨率为640X1164, 屏幕尺寸为4英寸,根据勾股定理(a^2 + b^2 = c^2)640^2+1164^2=1764496, 然后再对其开根号可求出屏幕对角线的分辨率为:1328,除以4可得出iphone5的dpi:1328/4≈332 可以看出iPhone5的屏幕的dpi约等于320, 刚好属于xhdpi, 直接把iPhone5的那一套切好的图片资源放入drawable-xhdpi文件夹里就ok了。
wrap_content VS dp
全是xhdpi的资源的话,那么你用wrap_content完全没有问题,Android会自动为其他规格的dpi屏幕适配,比如你在xhdpi放了一张120X120px大小的图片,那么在在hdpi屏幕上显示的就只有120/2*1.5=90px大小,但是如果你不小心同样把这张图片也放入了mdpi了,这个时候用wrap_content显示就会有问题。
例如假设你只在drawable_xhdpi文件夹下放了test图片,xhdpi的设备会去xhdpi文件夹下找到test图片并直接显示,而mdpi的设备优先会去mdpi文件夹里查找test图片,但是没找到,最后在xhdpi文件夹下找到,然后会自动根据density计算并缩放显示出来,实际显示出来的大小是120/2=60px, 所以整体的显示比例才会看起来比较正常
- mdpi
- xhdpi
但是如果你在mdpi文件夹里也放入了同样的图片,那么mdpi的设备会直接去mdpi文件夹里寻找到test图片,并直接显示,而这时候显示不会缩放,实际显示大小就是120X120,在mdpi的屏幕上看起来就会比较大,如图:
最小宽度限定词
当你的设备的最小宽度等于600dp或者更大时,系统选择layout-sw600dp/main.xml(two_panes)的布局,而小一点的屏幕则会选择layout/main.xml(single_panes)的布局。
避免出现重复的布局文件
layout-sw600dp和layout-xlarge同时存在,建立不同的values文件夹的layout.xml
比如有一个布局要兼容大小屏幕,在Activity中引入的布局名字为activity_my_schedule:
在 res文件夹下创建不同的 values文件夹,来指向同一布局文件
res/values/layout.xml
<resources>
<item name="activity_my_schedule" type="layout">@layout/activity_my_schedule_wide</item>
</resources>
res/values-sw600dp\layout.xml
<resources>
<item name="activity_my_schedule" type="layout">@layout/activity_my_schedule_wide</item>
</resources>
你可以只使用一个layout布局文件,在 res文件夹下创建不同的 values文件夹,来指向不同的局文件。
我们来看Google开源项目Iosched中的实际应用,在layout下面有两个布局文件,分别用于适配大小屏幕:
res/layout/activity_my_schedule_wide
res/layout/activity_my_schedule_narrow
创建不同的values文件夹的layout,layout用于小屏幕,values-sw600dp-land用于横屏的情况:
res/values/layout.xml
<resources>
<item name="activity_my_schedule" type="layout">@layout/activity_my_schedule_narrow</item>
</resources>
res/values-sw600dp-land\layout.xml
<resources>
<item name="activity_my_schedule" type="layout">@layout/activity_my_schedule_wide</item>
</resources>
更复杂的需求,不同的情况选择不同的布局,只需要在res下面建立不同的values的layout,引用指定的布局名称即可,常见的values类型有:
- res/values/layouts.xml
- res/values-sw600dp-land/layouts.xml
- res/values-sw600dp-port/layouts.xml
- res/values-xlarge-land/layouts.xml
- res/values-xlarge-port/layouts.xml
使用点9图片
如果你在使用组件时可以改变图像的大小,你很快就会发现这是一个不明确的选择,因为运行的时候,图片会被拉伸或者压缩(这样容易造成图像失真)。
避免这种情况的解决方案就是使用点9图片,这是一种能够指定哪些区域能够或者不能够拉伸的特殊png文件。