Android -- 屏幕适配


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

Android -- 屏幕适配

  • xhdpi

Android -- 屏幕适配

但是如果你在mdpi文件夹里也放入了同样的图片,那么mdpi的设备会直接去mdpi文件夹里寻找到test图片,并直接显示,而这时候显示不会缩放,实际显示大小就是120X120,在mdpi的屏幕上看起来就会比较大,如图:
Android -- 屏幕适配

最小宽度限定词

当你的设备的最小宽度等于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文件。

我是天王盖地虎的分割线




本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4703019.html,如需转载请自行联系原作者

上一篇:如何精简Unity中使用的字体文件


下一篇:MySQL的死锁系列- 锁的类型以及加锁原理