android不同分辨率适配
⑴ Android 屏幕分辨率适配
Android屏幕分辨率千奇百怪,怎么让app在不同的分辨率的设备上“看起来一样”呢?
你也许还有以下疑惑:
这篇文章将会针对以上问题一一解答。
Pixels 我们看到屏幕上的图像由一个个像素组成,像素里包含色彩信息。
如常说的手机分辨率:1080 x 1920 指的是手机宽度可展示1080像素,高度可展示1920像素。
Pixels Per Inch 每英寸长度所具有的像素个数,单位面积内像素越多,图像显示越清晰。
ppi一般用在显示器、手机、平板等描述屏幕精细度。
Dots Per Inch 每英寸长度所具有的点数。
dpi一般用来描述打印(书本、杂志、电报)的精细度
density-independent pixels (device-independent pixels 我查了一下,官网更多时候使用前者,有的时候也显示后者),dip是缩写,也可以更简单些称作dp。该单位的目的是屏蔽不同设备密度差异,后面细说。
Scalable pixels 用于设置字体,在用户更改字体大小时候会适配。
澄清了基本概念,我们现在从一个例子开始说明以上单位之间的区别与联系。
布局文件里有个View,长宽都是200px,分别在分辨率为480(宽)x800(高)简称A设备、1080(宽)x1920(高)简称B设备,效果如下:
左边是A设备,右边是B设备。问题出来了,同样长宽都是200px,为啥A设备显示很大,B设备显示很小呢?你可能会说B设备的横向分辨率1080比A设备的480大,所以在B设备上看起来比较小。来看看A、B设备横向到底是多少英寸,怎么来计算呢?这时候就需要用到ppi了,既然知道横向的像素点个数,也知道每英寸能容纳的像素点,当然可以得知横向的尺寸了。
其中一种方式获取DisplayMetrics对象:
A设备宽度尺寸:480(px)/240(ppi)=2inch
B设备宽度尺寸:1080(px)/420(ppi)=2.5inch
可以看出,A、B设备尺寸差别不大。A设备ppi=240 B设备ppi=420,明显地看出B设备单位长度上比A设备能够容纳更多的像素,因此同样的200px,B设备只需要较小的尺寸就能够显示,因此在B设备上的view看起来比A设备小很多。
知道了问题的原因,然而显示的效果却不能接受。
我们总不能自己判断每个设备的ppi,然后计算实际需要多少像素,再动态设置view的大小吧,那layout里的静态布局大小就无法动态更改适应了。想当然的能有一个统一的地方替我们转换,没错!Android系统已经帮我们实现了转换。接下来就是dpi、dp出场了。
Android系统使用dpi来描述屏幕的密度,使用dp来描述密度与像素的关系。
A设备dpi=240
B设备dpi=420
Android系统最终识别的单位是px,怎么将dpi和px关联起来呢?,答案是dp。
Android规定当dpi=160时,1dp=1px,当dpi=240时,1dp=1.5px,依此类推,并且给各个范围的dpi取了简易的名字加以直观的识别,如120<dpi<=160,称作为mdpi,120<dpi<=240 称作hdpi,最终形成如下规则:
现在知道了dp能够在不同dpi设备上对应不同px,相当于中间转换层,我们只需要将view长宽单位设置为合适的dp,就无需关注设备之间密度差异,系统会帮我们完成dp-px转换。将我们之前的例子稍微更改,再看看效果验证一下:
通过上面对dp的了解,我们知道在设定view大小、间距时使用dp能最大限度地屏蔽设备密度之间的差异。可能你就会问了,那bitmap展示的时候如何适配不同密度的设备呢?
自定义view从磁盘上加载一张图片,并将之显示在view上,view的大小决定于bitmap大小。依旧以上述A、B设备为例,展示结果如下:
左边是A设备,右边是B设备。
明显地看出,在A设备显示比B设备大很多,实际上和我们之前用px来描述view的大小原理是一样的,bitmap的宽、高都是px在描述,而bitmap决定了view的宽、高,最终导致A设备和B设备上的view大小(宽、高像素)是一样的,而它们屏幕密度又不相同,因此产生了差异。
那不会每次都需要我们自己根据屏幕密度来转换bitmap大小吧?幸运的是,Android已经为我们考虑到了。
生成不同密度的目录有什么作用?
A设备dpi=240,根据dpi范围,属于hdpi
B设备dpi=420,根据dpi范围,属于xxhdpi
图片原始尺寸:photo1.jpg(宽高 172px-172px)
当我们想要在不同密度设备上显示同一张图片并且想要“看起来一样大时”。假设设计的时候以hdpi为准,放置photo1.jpg为172*172,那么根据计算规则在xxhdpi上需要设置photo1.jpg为:
现在hdpi和xxhdpi目录下分别存放了同名图片:photo1.jpg,只是大小不同。当程序运行的时候:
来看看效果:
左边A设备,右边B设备
针对不同的密度设计不同的图片大小,最大限度保证了同一图片在不同密度设备上表现“看起来差不多大”。
来看看A、B设备上图片占内存大小:
说明在B设备上显示photo1.jpg需要更多的内存。
上边只是列举了hdpi、xxhdipi,同理对于mdpi、xhdpi、xxxhdpi根据规则放入相应大小的图片,程序会根据不同的设备密度从对应的mipmap文件夹下加载资源。如此一来,我们无需关注bitmap在不同密度设备上显示问题了。
在mipmap各个文件夹下都放置同一套资源的不同尺寸文件似乎有点太占apk大小,能否只放某个密度下图片,其余的靠系统自己适配呢?
现在只保留hdpi下的photo1.jpg图片,看看在A、B设备上运行情况如何:
看起来和上张图差不多,说明系统会帮我们适配B设备上的图片。
再来看看A、B设备上图片占内存大小:
先看A设备:
对比photo1.jpg 分别放在hdpi、xxhdpi和只放在hdpi下可以看出:B设备上图片所占内存变小了。为什么呢?接下来从源码里寻找答案。
A、B设备同样加载hdpi/photo1.jpg,返回的bitmap大小不相同,我们从这方法开始一探究竟。
上面涉及到的关键点是density,分别是TypedValue的density和Options的density。
先来看看TypedValue density:
再来看看Options density
现在分析B设备加载hdpi/photo1.jpg如何做的:
和我们之前调试的结果一致。
B设备是怎么决定使用hdpi下的图片资源呢?
根据实验(尝试找了源码,没怎么看懂,因此只是做了实验,可能在不同密度设备上找寻规则不一样):B设备先找属于自己密度范围文件夹下的图片,B设备属于xxhdpi,先查看xxhdpi有没有photo1.jpg,如果没有则往更高的密度找,比它高的密度是xxxhdpi,还是没有,则往低密度找,找xhdpi,没有再找hdpi,找到了则返回构造好的TypedValue,剩下的就是我们前面分析的。
既然我们只想放某个密度下的一份切图,该放哪个密度下呢?从系统寻找规则看,更推荐放置在更高密度下的,因为如果放在低密度下,那么当运行在高密度设备上时,图片会进行放大,可能导致不清晰。我一般习惯放在xxhdpi下。
Android Studio默认创建了不同密度的mipmap文件夹,默认放置了ic_launcher.png。我们普通的切图该放drawable还是mipmap下呢?对于这个问题网上也是众说纷纭,实际上对于我们来说,关注的重点是图片放在drawable或者mipmap,加载出来bitmap是否有差异,如果没有差异放在哪就看习惯了。通过实践,普通的切图放drawable和mipmap下加载出来的bitmap是没有差异的,只不过用drawable的话需要自己创建不同密度的文件夹。我习惯于放在drawable下(启动图标logo还是放在mipmap下)。
前边 [注1] 留了个问题,我们使用dp来表示view的大小了,为啥两个看起来还是有些差距?下面我们更加直观地看一个例子。
A设备dpi=240 密度1.5 分辨率(宽高px):480 * 800
B设备dpi=420 密度2.625 分辨率(宽高px):1080 * 1794
换算成dp
A设备分辨率:320dp * 533dp
B设备分辨率:411dp * 683dp
依旧是上边的例子:
将view宽高分别设置为320dp,看看效果:
左边A设备,右边B设备
可以看出同样的320dp大小,A设备铺满了屏幕,而B设备没有。这效果显然是不能接受的,Android考虑到不同设备宽高不同,推出了"宽高限定符"。以A、B设备为例:
在res文件夹下创建文件夹:
假设设计师出图是按照800x480,那么我们创建dimen文件的时候
该文件放在values-800x480文件夹下。
根据分辨率比例算出1794x1080的dimen值
这样子,A、B设备加载资源的时候使用对应分辨率限定符下的px,如果找不到再找默认值,可以在一定程度上解决屏幕宽高碎片化适配问题。
但是这样子的限定比较严格,需要测试各种分辨率,后来Android又推出了"smallest-width"简称最小宽度限制。
A设备宽320dp
B设备宽411dp
假设设计师切图标准屏幕宽是320dp(A设备),那么可以定义如下dimen.xml文件
该文件放在values-sw320dp文件夹下
根据规则,计算B设备dimen.xml
现在我们继续来看之前的view
通过对dimen引用,A设备寻找和自己宽度一样的dimen文件,找到values-sw320dp,dp320=320dp。B设备寻找和自己宽度一样的dimen文件,找到values-sw411dp,dp320=410dp。这样子同样的dp320,得出不同的值,就适配了屏幕宽度不同的问题。
看看效果:
这次B设备也铺满了屏宽。
综上,为了适配不同屏幕大小,推荐使用dp+smallest-width。
获取设备dpi最终都是从这方法获取的,实际上就是读取系统的配置文件。因此我们也可以通过adb shell 获取:
可以看出dpi是系统配置好的,当然有些手机是可以设置分辨率的,设置之后我们查看分辨率:
分辨率变低了,dpi也变小了。
⑵ android开发如何使一个apk文件适配不同的手机和pad的不同分辨率
dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。
px: pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。
pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用;
sp: scaled pixels(放大像素). 主要用于字体显示best for textsize。
由此,根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看
TextView
⑶ 初学android,问个问题。怎么样能让android的widget适配不同的分辨率进行布局呢
xml布局中,采用dp做单位,不用px。就可以解决你的问题。
新的sdk为了适配不同的屏幕分辨率的机型,已经陆续取消采用像素px作为布局单位。这主要是针对不同设备而言的。因为px不管在什么样的设备上都是那样长,但是dip会根据设备变化。
这涉及到dp和px的转换问题。
首先,240*320像素的手机(WQVGA/QVGA)的density=120;
320*480的手机(HVGA)的density=160;
480*800的手机(WVGA)density=240;
转换公式如下:
pixs =dips * (density/160)
dips=(pixs*160)/density
补充:
px:单位尺寸里的像素点
dp:一个基于density的抽象单位,如果一个160dpi的屏幕,1dp=1px
希望对你有帮助。
⑷ Android界面布局怎么样适应不同分辨率的手机
各种Android操作系统的手机简直就是琳琅满目,屏幕分辨率的差异可想而知。目前比较主流的有WVGA=800x480,HVGA=480x320,另外的还有QVGA=320x240。当然还有魅族M9的DVGA=960x640,还有蛋疼的摩托罗拉的FWVGA=854x480。
其实,在你layout的xml文件中,编写的时候是不是用了许多的padding呢?如果是,那你就蛋疼了。因为这样的布局永远是无法适应所有手机屏幕的。
正确的做法应该是使用的是weight属性。将你控件的layout中的width、height设置为fill-parent,不要使用wrap——content。因为wrap-content的大小是不固定的。而weight(权重)这个属性很好的解决了这个问题。
当包裹在控件外面的Layout的width、height属性都设置为fill-parent时,可以利用weight的反比特性。即如果控件A设置weight为5,控件B设置weight为7,那么A所占的空间为5/(5+7),B所占的空间为7/(5+7)。这样的反比属性对任何分辨率下的手机都是合适的。
当然,字体就不行了。那怎么保证字体能够跟布局一样能够自适应呢?
呵呵,很简单,就是在你的res文件夹中创建一个文件夹,叫做values-320x240。其中320x240是你手机屏幕的分辨率,根据你手机屏幕的情况做不同的命名,例如values-800x480。在该文件夹下创建一个dimens.xml文件,定义各种字体的大小。那么系统就会自动根据你手机屏幕的分辨率去调用响应的文件夹。
另外,值得提醒的是,记得在你默认的values文件下的dimens.xml文件中也要写上相应的字体大小哦,因为当系统无法认识你手机屏幕大小的时候,它会自动去找你默认文件中的
东西,没有写的话程序会崩溃。
************************************************************分割线************************************************************
在看下面内容之前首先请看你SDK文档中以下这篇文章
其实google在分辨率适应性的东西已经写的很清楚了,只是我们很多人没去看而已
以下是结论:
屏幕分辨率:1024x600
density:1(160)
文件夹:values-mdpi-1024x600
屏幕分辨率:1024x600
density:1.5(240)
文件夹:values-hdpi-683x400 由1024/1.5 600/1.5得到,需要四舍五入。
屏幕分辨率:800x480
density:1(160)
文件夹:values-mdpi-800x480
屏幕分辨率:800x480
density:1.5(240)
文件夹:values-hdpi-533x320 由800/1.5 480/1.5得到,需要四舍五入。
以此类推
一般情况下需要创建出values 、values-mdpi 、 values-hdpi文件夹,以备在一些没有规定的尺寸屏幕上找不到资源的情况。
然后在里面使用不同的dimens文件,Layout中不要使用显示的数字,所有的尺寸定义全都援引dimens里面的内容。
这样能够保证深度UI定制的情况
另外在工程的default.properties中如果split.density=false,则分辨率适配的时候文件夹命名不需要与scale相除
例
屏幕分辨率:800x480
density:1.5(240)
文件夹:values-hdpi-800x480
************************************************************分割线************************************************************
关于dimens
位置:res\values
单位:px Pixel 以画面的像素为单位;
in Inches以画面的多少英寸为单位;
mm Millimeter以画面的多少毫米为单位;
pt Points 一点为1/72英寸;
dp或dip Density-indepentdent 为160dpi屏幕的一个pixel;
ap Scale-independent Pixels 随屏幕尺寸改变的一个pixel;
1.drawable: 存放不同分辨率对应图片
在2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。
drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。
在2.1之前的版本可以通过drawable-800x480, drawable-480x320 等方式实现。
2:layout:放置对应不同分辨率的布局
创建不同的layout文件夹, layout-800x480,layout-480x320, 系统会根据屏幕的大小自己选择合适的layout进行使用。
另外:可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件。
下面列出主流的android机型有:
240x320低端,国产入门级采用,例如HTC G4,G8
320x480中端,大部分基于此分辨率,例如HTC G1,G2,G3,G6, MOTO ME600, SAMSUNG I7500
480x800中高端,大部分基于此分辨率,例如HTC G5,G7, MOTO MT810
480x854MOTO特有的,例如Droid, Milestone, XT800
960x640, 魅族M9
⑸ 怎么算设置多少 dp 才能让 Android 适应不同分辨率
Android中一个layout想适配各种屏幕尺寸那么需要按以下规则去写layout:
1. 尽量使用wrap_content、match_parent、weight 来规定layout的大小。
2. 要确保布局的灵活性并适应各种尺寸的屏幕,应使用 “wrap_content” 和 “match_parent” 控制某些视图组件的宽度和高度。
3. 使用 “wrap_content”,系统就会将视图的宽度或高度设置成所需的最小尺寸以适应视图中的内容,而 “match_parent”(在低于 API 级别 8 的级别中称为“fill_parent”)则会展开组件以匹配其父视图的尺寸。
4. 如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸,视图就会相应地仅使用自身所需的空间或展开以填满可用空间。此方法可让布局正确适应各种屏幕尺寸和屏幕方向。
5. 如果某些地方必须要规定控件的大小,那么要使用dp 或者 dip单位。
6. 字段必须使用 sp单位。
7. 将不同的图片放到不同的drawable目录下,分辨率的匹配规则如下:
drawable-mdpi 320 * 480
drawable-hdpi 480*800
drawable-xhdpi 720 * 1280
drawable-xxhdpi 1080 * 1920
drawable-xxxhdpi 1080+
⑹ Android 字体大小怎么自适应不同分辨率
字体大小好此一般迅袜空是sp,控件大亩瞎小采用dp, android 手机一般牵涉到适配的问题,基本有几个原则:
默认配置一般都是根据目前主流的分辨率来设置,比如现在都是4.7寸以上,720p,1080p这2个,可以默认为720p。这样就可以覆盖大多数的手机了。
剩余的小部分就只能根据values增加后缀 比如 -480*800增加配置文件来适配480*800分辨率的手机,来适配不同的分辨率了
在代码里面获取屏幕分辨率,动态修改字体大小
⑺ android开发,html5页面怎么适配不同手机分辨率
按照比较普遍的最低分辨率写 其他的 两边留空白呗