基础知识:

屏幕密度:

Density-independent pixel (dp):密度无关像素单位(一个相对的值)。1dp 的大小相当于一个 160 dpi 屏幕上一个像素的大小。

计算方法:px = dp * (dpi / 160)。这个公式说明,比如一个10寸屏幕分辨率为 1280*800,另一个10寸屏分辨率为 2560*1600。比如在 layout 文件中有一个图片大小为 60dp。那么根据公式,两者显示效果大体是一样的,区别是图片清晰度不同。

也就是说,安卓设备的屏幕以屏幕密度大小来划分,界面设计使用与屏幕密度无关的 dp 为单位,这样可以提高不同屏幕密度下的兼容性。

dpi (dots per inch):每寸像素数。分为 ldpi 低(~120dpi),mdpi 中(~160dpi),hdpi 高(~240dpi),xhdpi 超高(~320dpi) ,nodpi 密度无关资源:不会对资源根据屏幕密度缩放。

160 dpi 的大小相当于:(320*240)分辨率,物理尺寸是(2英寸*1.5英寸)的屏幕。

比如两个1280*800的屏幕,尺寸分别为10寸和5寸。在一个 layout 上有一个 640dp*400dp 的图片。由于小屏幕的 dpi 是大屏幕的二倍,所以对于同样 dp 的图片,在小屏幕上显示用的像素是大屏幕的二倍。而两者像素数相同,所以显示出来的效果是小屏幕上会显示出一个是大屏幕上二倍大的图片(相对大小)。绝对大小他们是一样的。所以屏幕适配时必须要看屏幕密度,屏幕密度高的需要调小 dp 值以保证有同样的显示效果。

所以,屏幕适配的原理是:

对 layout 要用屏幕大小来划分:

  • layout-xlarge screens are at least 960dp x 720dp
  • layout-large screens are at least 640dp x 480dp
  • layout-normal screens are at least 470dp x 320dp
  • layout-small screens are at least 426dp x 320dp

对 图片 要用屏幕密度 dpi 来划分:

  • drawable-ldpi (low)
  • drawable-mdpi (medium)
  • drawable-hdpi (high)
  • drawable-xhdpi (extra high)

常见 Android 设备尺寸(dp):

https://design.google.com/devices/

字体大小的适配:

和 dp 的理论一样,字体大小使用同样密度无关的单位 sp。用法也与 dp 一样。

在代码中,想要使用 dimen 里面设置的 sp 字体大小应该这样做:

  1. textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.textSize1));

而不能这样:

  1. textView.setTextSize(getResources().getDimension(R.dimen.textSize1));

因为如果不明确是 TypedValue.COMPLEX_UNIT_PX 的话,系统会自动根据屏幕密度来返回一个像素值。注意要用 TypedValue.COMPLEX_UNIT_PX 而不是 TypedValue.COMPLEX_UNIT_SP

****************************************************************************************************************

实践:

1. 屏幕对多分辨率适应的最好方法可能就是用 weight 属性了。

线型布局里可以使用 layout_weight 属性来让控件按比例显示。这样不同屏幕分辨率下会有一致的显示效果。

这个属性有两种使用方法:

  1. 把 layout_width 或 layout_height (取决于你想在长度上还是宽度上按比例显示) 的值设为 match_parent 。

  这种情况下,weight 值越小,占的地方越大。这种方法缺点是比例需要自己计算,因为它是反的。

  2. 把 layout_width 或 layout_height (取决于你想在长度上还是宽度上按比例显示) 的值设为 0 px 。

  这种情况下,weight 值越大,占的地方越大。

但是 weight 属性对相对布局是无效的。所以在使用时需要注意。

************************************************************************************

2. 也可能用代码获取屏幕分辨率的方式布局。优点是准确,缺点是麻烦。因为在所有控件的大小都需要在代码里重新设置,非常麻烦。这种方法不适合项目里有很多 layout 的情况。

3. 另外也可以为每个分辨率单独设计一个布局。缺点还是麻烦,因为分辨率有那么多种。优点是还是准确。

4:3 平板屏幕适配:

对于安卓平板,标准屏幕比例是 16:9。所以对于平板应用,平常只对这个比例支持。如果想支持 4:3 的平板,需要对 layout 里的各控件的大小进行重新计算,并且使用 4:3 比例的背景图片。

那么问题来了,如果根据平板尺寸判断屏幕比例并适配呢?这个问题比较复杂,我做了很多尝试。

res 文件夹下存放所有资源,包括 values,layout,drawables 等。values 和 layout 常用 sw(最短宽度)这个参数,而 drawable 常用屏幕密度来划分。很明显这些都不适用于这个情况。

有一个参数 long/notlong,表示屏幕是否是长屏幕。什么样算长?我没有具体的数据,但在测试的时候,一个 1280*800 物理按键的10寸屏幕不是长屏幕。而如果同样分辨率和尺寸的没有物理按键的屏幕却是长屏幕。一个 1024*768 的屏幕当然一定不是长屏幕。所以除非是没有物理按键的 16:9 平板,否则无法通过这个参数来区分 16:9 还是 4:3。

解决办法是什么呢,测试中发现的解决办法是用屏幕尺寸区分。w1024dp 这个参数可以区分出一个宽度为 1024dp 的屏幕。以三星TAB A为例,9.6寸,1024*768,1024dp*768dp。这个参数对它适用。但是如果一个平板尺寸为 1024dp*600dp,那就得着急了。另外如果世界上存在小尺寸的 4:3 平板,那屏幕尺寸就很可能不是 1024dp*768dp,那么这个适配方法也会失效。所以真正一劳永逸的解决办法还在寻找中。

有一篇文章可供参考:

http://www.eoeandroid.com/thread-173973-1-1.html

最近找到了最佳解决办法:

其实早就知道 9-patch (.9) image。只是最近才测试成功。

思路是这样的,9-patch 中分为“横向可拉伸”,“纵向可拉伸”,“四周都可拉伸”,“不拉伸”四个区域。 背景图中的不想拉伸的部分,放在“不拉伸”区域。其他的就很随意了,随便它怎么拉。“不拉伸”区域在四个角上,所以即使图片中包含多个比较分散的不想被拉伸的部分也没有问题。

使用 9-patch 可以进一步压缩图片尺寸,可拉伸的部分可以省掉。真的是一举多得。

程序中使用 9-patch 的注意事项:

1. 要使用 ImageView,而且要用做 src 而不是 background。

2. 要使用 scaleType = “centerCrop”

  如果使用 center,不拉伸,保持图片比例,图片尺寸和 ImageView 不符合的时候无法填满。

  默认是 fitCenter,保持图片比例,拉伸,但和ImageView 不符合的时候无法填满。

  其他的也都测试过都不符合。

  centerCrop 是保持图片比例并拉伸,另外一个特性是它会根据 ImageView 的宽度来充满。

制作工具:

android studio,9-patch generator 等。

参考文章:

http://www.cnblogs.com/vanezkw/archive/2012/07/19/2599092.html

今天测试中发现,或许起作用的并不是 9-Patch。而是 ImageView 的 centerCrop 属性。所以对于这个问题,其实这一个参数就能解决。

Android 屏幕适应的更多相关文章

  1. Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案

    的最佳方案 标签: Android屏幕旋转AsyncTaskProgressDialog 2014-07-19 09:25 39227人阅读 评论(46) 收藏 举报 分类: [android 进阶之 ...

  2. android 屏幕分辨率 更改

    手头上有一个320x240的LCD.运行android时,显示内容过大,需要更改屏幕的分辨率. 参考链接 http://www.bkjia.com/Androidjc/899396.html http ...

  3. Android屏幕适配全攻略 (转载)

    http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...

  4. 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

    来源:http://blog.csdn.net/zhaokaiqiang1992 更多:Android AutoLayout全新的适配方式, 堪称适配终结者 Android的屏幕适配一直以来都在折磨着 ...

  5. Android屏幕适配全攻略(最权威的官方适配指导)(转),共大家分享。

    Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因.重要概念.解决方案及最佳实践,我相信如果你能认真的学习 ...

  6. Android屏幕适配全攻略(最权威的官方适配指导) (转)

    招聘信息: Cocos2d-X 前端主程 [新浪微博]手机客户端iOS研发工程师 20k-40k iOS 开发工程师 iOS高级开发工程师(中国排名第一的企业级移动互联网云计算公司 和创科技 红圈营销 ...

  7. 腾讯优测| 让Android屏幕适配开发更简单-Google百分比布

    文/腾讯优测工程师 吴宇焕 腾讯优测优社区干货精选~ 相信开发同学都被安卓设备碎片化的问题折磨过,市面上安卓手机的主流屏幕尺寸种类繁多,给适配造成很大的困难.就算搞定了屏幕尺寸问题,各种分辨率又让人眼 ...

  8. Android 屏幕适配(一)百分比布局库(percent-support-lib) 解析与扩展

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46695347: 本文出自:[张鸿洋的博客] 一.概述 周末游戏打得过猛,于是周 ...

  9. Android重写getResources规避用户调整系统字体大小影响Android屏幕适配

    Android屏幕适配一直是一个头疼的问题.除此之外还要考虑APP在实际应用场景中,用户千奇百怪的设置,最常见的用户设置行为就是设置手机的字体大小,比如把字体设置成超大或者超小,这对屏幕适配又带来额外 ...

  10. android屏幕基础知识

    首先,先来上一张图,看看android屏幕分辨率的占比情况 什么是dp,dip,dpi,sp.px ?之间的关系是什么? px:构成图像的最小单位 dp/dip:密度无关像素 以160dpi为基准 1 ...

随机推荐

  1. [转]js清除所有cookies

    来源:http://blog.csdn.net/zzl1120/article/details/6592332 var cookies = document.cookie.split(";& ...

  2. selenium webdriver——JS滚动到最底部

    JS控制滚动条的位置: window.scrollTo(x,y); 竖向滚动条置顶 window.scrollTo(0,0); 竖向滚动条置底 window.scrollTo(0,document.b ...

  3. java递归之“二叉树”

    物有本末,事有始终,知所先后,则近道矣.-----题记. BotWong半路入行it做码农,也就半年时间,竟“不知天高地厚”地来到了深圳闯天下.一口气投了百个简历,一周后终于有公司邀约面试,除了基础的 ...

  4. python实现进度条--主要用在上传下载文件

    在python中进行socket上传文件的时候使用进度条,然后在网上找了好久,找寻相关的进度的条的使用,看了几个,发现总是无法进行调用,主要原因是在进行上传文件的时候,每次传送的数据量是固定的,数据的 ...

  5. dsm 黑 离线转码 备忘

    6.2以后不行 我用的是 DS3617_6.17-15284 进入下载安装文件和工具 1安装 .套件来源增加 packages.synocommunity.comb.设置信任级别为任何发行者 c.找到 ...

  6. react-native 生命周期

    一.前言 问: 什么是组件的生命周期? 组件的生命周期中都包含哪些方法,各有什么作用? 生命周期的方法都在什么时候调用? 生命周期: 顾名思义,一个主体从出生到死亡的整个过程 学习组件(React的基 ...

  7. 使用SQL查询所有数据库名和表名

    使用SQL查询所有数据库名和表名 MySQL中查询所有数据库名和表名 查询所有数据库 show databases; 1 1 查询指定数据库中所有表名 select table_name from i ...

  8. GPS坐标转换为百度地图坐标

    /** * GPS坐标转换为百度地图坐标 * 需要引入javabase64.jar 和json的一些包 * */ public class Gps2BaiDu { public static void ...

  9. Bitmap Images and Image Masks

    [Bitmap Images and Image Masks] Bitmap images and image masks are like any drawing primitive in Quar ...

  10. AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)(转)

    出处:http://www.bubuko.com/infodetail-827612.html AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI ODat ...