导航:首页 > 操作系统 > android屏幕尺寸适配

android屏幕尺寸适配

发布时间:2022-11-17 03:45:22

android-屏幕适配全攻略(绝对详细)(一)

关键字: 屏幕适配 px dp dpi sp large限定符 .9.png

前言: 这篇文章依然是我在 [慕课网 ][h]学习 凯子哥 的同名视频 Android-屏幕适配全攻略 ,所记录下来的笔记---凯子哥讲得真的超详细。
[h]: http://www.imooc.com/ "MOOC"

从上图可以看出,主流的分辨率是前六种:1280×720、1920×1080、800×480、854×480、960×540、1184×720,不过我们有解决方案。看完这篇文章,想必你就可以解决常见的屏幕适配问题。

接下来正式进入正题。

介绍几个在Android屏幕适配上非常重要的名词:

屏幕尺寸 是指屏幕对角线的长度。单位是英寸,1英寸=2.54厘米
屏幕分辨率 是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向像素横向像素,如1280×720
屏幕像素密度 是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写,像素密度和屏幕尺寸和屏幕分辨率有关

dip: Density Independent Pixels(密度无关像素)的缩写。以 160dpi 为基准,1dp=1px
dp: dip
dpi: 屏幕像素密度的单位,“dot per inch”的缩写

px: 像素,物理上的绝对单位

sp: Scale-Independent Pixels的缩写,可以根据文字大小首选项自动进行缩放。Google推荐我们使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,最好不要使用奇数和小数。

用于区分不同的像素密度。

在Google官方开发文档中,说明了 ** mdpi:hdpi:xhdpi:xxhdpi:xxxhdpi=2:3:4:6:8 ** 的尺寸比例进行缩放。例如,一个图标的大小为48×48dp,表示在mdpi上,实际大小为48×48px,在hdpi像素密度上,实际尺寸为mdpi上的1.5倍,即72×72px,以此类推。

我们可以通过以下几种方式来支持各种屏幕尺寸:

wrap_content: 根据控件的内容设置控件的尺寸
math_parent: 根据父控件的尺寸大小设置控件的尺寸
weight: 权重,在线性布局中可以使用weight属性设置控件所占的比例

例如,我们要实现下图所显示的效果:当屏幕尺寸改变时,new reader控件两边的控件大小不变,new reader控件会占完剩余的空间。

具体布局文件如下:

小插曲: 关于 android:layout_weight 属性

一般情况,我们都是设置要进行比例分配的方向的宽度为0dp,然后再用权重进行分配。如下:

效果为:

效果为:

button1宽度=L+(L-2L)×1/3=2/3L
button2宽度=L+(L-2L)×2/3=1/3L

当然,还有其他的方式,都可以运用此公式进行计算。
在实际开发中,我们一般使用0dp的方式,而不使用其他方式。

简单的布局一般都使用 线性布局 ,而略微复杂点的布局,我们使用 相对布局 ,大多数时候,我们都是使用这两种布局的嵌套。

我们使用 相对布局 的原因是, 相对布局 能在各种尺寸的屏幕上保持控件间的相对位置。

res/layout/main.xml 单面板:

res/layout-large/main.xml 双面板:

如果这个程序运行在屏幕尺寸大于7inch的设备上,系统就会加载 res/layout-large/main.xml 而不是 res/layout/main.xml ,在小于7inch的设备上就会加载 res/layout/main.xml 。

需要注意的是,这种通过 large 限定符分辨屏幕尺寸的方法,适用于android3.2之前。在android3.2之后,为了更精确地分辨屏幕尺寸大小,Google推出了最小宽度限定符。

res/layout-sw600dp/main.xml ,双面板布局: Small Width 最小宽度

这种方式是不区分屏幕方向的。这种最小宽度限定符适用于android3.2之后,所以如果要适配android全部的版本,就要使用 large 限定符和 sw600dp 文件同时存在于项目 res 目录下。

这就要求我们维护两个相同功能的文件。为了避免繁琐操作,我们就要使用布局别名。

由于后两个文具文件一样,我们可以用以下两个文件代替上面三个布局文件:

res/layout/main.xml 单面板布局
res/layout/main_twopanes.xml 双面板布局

然后在 res 下建立
res/values/layout.xml 、
res/values-large/layout.xml 、
res/values-sw600dp/layout.xml 三个文件。

默认布局
res/values/layout.xml :

Android3.2之前的平板布局
res/values-large/layout.xml :

Android3.2之后的平板布局
res/values-sw600dp/layout.xml :

这样就有了 main 为别名的布局。
在activity中 setContentView(R.layout.main);

这样,程序在运行时,就会检测手机的屏幕大小,如果是平板设备就会加载 res/layout/main_twopanes.xml ,如果是手机设备,就会加载 res/layout/main.xml 。我们就解决了只使用一个布局文件来适配android3.2前后的所有平板设备。

如果我们要求给横屏、竖屏显示的布局不一样。就可以使用 屏幕方向限定符 来实现。
例如,要在平板上实现横竖屏显示不用的布局,可以用以下方式实现。
res/values-sw600dp-land/layouts.xml :横屏

res/values-sw600dp-port/layouts.xml :竖屏

自动拉伸位图,即android下特有的 .9.png 图片格式。

当我们需要使图片在拉伸后还能保持一定的显示效果,比如,不能使图片中的重要像素拉伸,不能使内容区域受到拉伸的影响,我们就可以使用 .9.png 图来实现。

要使用 .9.png ,必须先得创建 .9.png 图片,androidSDK给我们提供了的工具就包含 .9.png 文件的创建和修改工具。双击 SDK安装目录 oolsdraw9patch.bat ,就会打开下图所示的窗口。

下面是一个例子:

Button属性设置:

如果我们选择的内容区域偏差太大,可能就不会显示出text值 BUTTON 。

好了,这篇文章写的有点多了,剩下的内容放在 下篇文章 记录吧。
内容提要:
解决方案-支持各种屏幕密度
解决方案-实施自适应用户界面流程

未完待续

② android屏幕适配有哪些方法

Android 资源文件夹有其中两种方式支持屏幕适配:
一、方法:
1.XXX XXX-ldpi XXX-mdpi XXX-hdpi XXX-xhdpi XXX-xxhdpi 这种方式 (推荐使用)
2.XXX XXX-123x456 后面是具体值(不推荐使用这种方式!)
当我们做适配处理时通常会在以上一堆文件夹中定义 xxx.xml 例如 定义一个 : <dimen name="list_item_height">100dip</dimen>
二、适配举例:
Android的匹配机制和手机系统有关:
规则一:Android4.0 以上的手机,先寻找和设备吻合的文件夹里的相应文件里的资源,如果没有找到会继续匹配它下面(比它分辨率或密度小)的一些文件夹,最后去XXX 默认文件夹中匹配。
eg1: 小米2s (4.1 1280x720) 有文件夹 XXX XXX-320x240 XXX-800x480 XXX-1280x719 XXX-1280x720 XXX-1280x721 XXX-xhdpi
1.匹配XXX-xhdpi
2.匹配XXX-1280x720
3.匹配XXX-1280x719
4.匹配XXX-480x800
5.匹配XXX-320x240
6.匹配XXX
eg2:HTC ONE (4.2 1920×1080)
规则二:Android4.0 以下的手机,先寻找和设备吻合的文件夹里的相应文件里的资源,如果没有找到会继续匹配它下面(比它密度小)的一些文件夹。
eg:三星m250L(同三星9100 2.3.7 800x480) 有文件夹 XXX XXX-320x240 XXX-800x479 XXX-480x800 XXX-ldpi XXX-mdpi XXX-hdpi
1.匹配XXX-hdpi
2.匹配XXX-mdpi
3.匹配XXX-480x800
4.匹配XXX
5.匹配XXX-ldpi
6.程序退出
eg3:华为U8860(2.3.6 854x480)
所以在项目中<dimen name="list_item_height">50dip</dimen> 分别定义在
values : <dimen name="list_item_height">50dip</dimen> 和
values-320x240 : <dimen name="list_item_height">42dip</dimen> 中.
小米2s 会取 values-320x240 中42dip 的值。

③ android屏幕适配

android设备碎片化严重,因此在实际开发的时候需要做屏幕适配
适配主要是在以下几个方面:

常见的布局适配主要是以下几点:
a.避免写死布局尺寸,使用wrap_content或者martch_parent
b.使用权重,比如linearlayout中的weight;
c.使用relative的相对位置摆放,比如layout_centerInParent="true"
d.ConstraintLayout 原理类似于relatvie,相对摆放,但是性能相对于relatvie会好一点
e.android官方的库Percent-support-lib,该库主要是用的是百分比适配

a. .9图适配,这个是使用了.9图可以在特别区域拉伸不失真的特性来适配
b. 使用多套位图,匹配不同的分辨率,比如在mipmap,mipmap-xhdpi,mipmap-xxhdpi,等文件夹下面放多套分辨率不同的内容相同的图片

是指同一个业务逻辑,在不同的设备上执行不同的跳转方式,比如在手机上打开一个新的activity,但是在平板上,可以在横屏状态下,右侧增加一个fragment,展示打开的页面。

a.分辨率限定符,使用drawable-dpi,drawable-hdpi等
b.尺寸限定符
c.最小宽度限定符
d.屏幕方向限定符

a.android9.0开始 有官方的api进行适配
b.华为,小米,魅族,vivo,oppo各大room厂商有对应的api进行适配

除了以上这些,还有dimens适配,但是都各有缺点,有的需要多套图,有的需要多套资源文件,dimens适配的dimens文件过多,需要针对不同的屏幕分辨率来生成对应的文件,比较繁琐

以上,实际开发中,做的最多的适配为布局适配

开发中屏幕适配的核心是在于屏幕缩放,不论是哪种屏幕适配,都是以这个缩放为基础

已知:设计图手机像素(W,H),设计图上控件的像素值(ViewW,ViewH),目标设备分辨率(TargetW,TargetH)
求:目标设备上view的宽高(TargetViewW,TargetViewH)
公式:宽:ViewW / W * TargetW=TargetViewW
高:ViewH / H * TargetH =TargetViewH
原理:根据当前设备的分辨率,计算出设计图上的控件在该设备上的缩放比,然后根据缩放比,来动态的设置view, 最终换算出来的单位为px
该适配方式是通过自定义外部的ViewGroup,比如LinearLayout,RelativeLayout,在onMeasure方法中,遍历子view,设置宽高以及padding,margin
以下是封装了一个工具类,用来获取屏幕宽高以及计算缩放比:

未完待续

④ Android 屏幕适配

Android的屏幕大同小异,分辨率也是各种各样,手机App上的差异性还没那么明显,基本用Dp & weight就可以比较好的适配各种手机。但是在Pad上的表现就不尽如意,而且发现像华为Pad Pro这种高端设备,是可以通过系统设置去设置修改系统的density值,导致整个如果只用一套DpUI布局去实现,会出现很奇怪的UI效果,基本不能适配。这时候就需要对UI进行适配。通过资料查询,需要了解如下的几个概念

1.px,pixel 就是像素,最基本的真实显示单位
2.dp,dip, Density-independent pixel,设备的独立像素,1dp表示在屏幕像素点密度为160ppi时1px长度
3.ppi, pixel per inch ,每英寸对角像素点,这个是物理上的
4.dpi, dot per inch ,每英寸多少个点,这个是软件上的,这里的点跟像素点不同
5.sp: scale-independent pixel, 字体大小单位

简单换算就是
ppi =根号( 横屏像素点平方+纵屏像素点平方)➗对角线的长度,这个长度是一英寸

1dp = (dpi/160) px
然后有些不同尺寸手机的ppi可能是420, 430, 440, 450, 460.,由于物理ppi上是固定的,改变不了,为了适配,通过人为设置一个dpi,来规范这些差不多ppi值,使得这些相差差不多的屏幕都是通用一个dpi,也就是使用同一套设计方案。
一开始通过dp值来实现适配,是可以解决大部分适配问题,但是在遇到pad这种设备,由于是横屏,而且系统设置还可以修改density值,使得用一套固定屏幕(比如1280 * 800)的方向变得不是那么合适。

这时候想到可以通过Android中 dimens中定义dimen值,Android中可以通过sw去搜索对应的dimen值表来获取对应的配置,smallestWidth适配,sw限定符适配,只要我们把对应的表通过换算,得到一个新值,就可以得到在不同的density值中得到对应的dp值表,解决华为上一个设备对应不同density值的问题。
那么问题来了,如果去得到sw不同的dimens呢,网上的方法很多,有些自己写脚本,有些自己写程序生成,为了就是列举所有的值,一般1-1000dp,然后基于一个基准,比如360dp宽度,去换算出不同屏幕宽度的dimens值,这里我推荐Android Studio的插件ScreenMatch,先安装插件

然后在values中创建dimens文件夹,并创建dimens.xml,其中写上自己定义的dp值,如下

然后在该文件右键,选择screenmatch

插件就会生成一堆其他屏幕的dimens文件,并且自动生成1-800的其他dp值,基本满足开发中的定义,如果没有的话,就自行在这里定义,然后重新生成。
关于ScreenMatch的生成还有一个基准,就是基于那个dpi来生成,通过插件生成,在根目录会多出了两个文件,一个example, 一个config文件

这里我们看看properties文件,内容如下

其中base_dp=850就是基于850,然后可以通过match_dp去调整要适配的dpi值。
通过这方方式,会在dimens文件自动生成dimen文件

在网上看到,还可以通过修改density去修改,这种方式有空我在试试

⑤ Android切图适配知识点汇总

对于在工作中没有接触过安卓版本app,或是面试的时候会被问到安卓分辨率等问题,可以通过本文对安卓切图有所了解。我在以往的工作中也没有接触过安卓设计等一系列问题,但是看完一些文章后,大致对安卓分辨率等知识点有所了解。此文是对自己所了解到的知识做一个总结,也希望能帮助到不了解安卓一系列问题的同行们,好啦,马上进入正题!

基本概念
1、手机屏幕尺寸计算方式:对角线尺寸/2.54(1英寸=2.54厘米)
2、分辨率:屏幕上显示的像素个数,单位尺寸内像素点越多,显示的图像就越清楚。

上图中红框框出来的是现在市场上主流的分辨率,只要记这三个就可以。其他的已被淘汰。

3、屏幕密度:屏幕每英寸有多少个像素。
4、单位:dp是开发中用于描述尺寸和间距。
sp是用于描述字号和行距。

用哪种分辨率来设计?
原则上需要为不同的分辨率去单独设计效果图,但由于实际情况,只需要采用一种分辨率去设计,目前多数采用720*1280的分辨率。

需要提供几套切图?
只需要一套切图即可
720*1280尺寸的切图可以适配其他机型,有些特殊的切图需要单独适配的,比如icon等。
适配480 800的机型,只需要把切图/1.5即可。
适配1080
1920的机型,只需要把切图*1.5即可。适配此分辨率的时候,需要在720 1280下画图的时候,尽量采用矢量图形来画图。
例如,图标是48
48的时候,适配1080 1920点时候,48px*1.5=72px.把矢量图形调整为72px即可。开发会把切图放到xxhdpi的文件目录下,就会自动适配1080 1920
同样,适配480 800的时候,48px/1.5=32px.开发把切图放到hdpi文件目录中,会自动适配。
720
1280的切图,开发放到xhdpi的目录下。
注:设计图片的时候尽量采用偶数。

需要提供几套标注?
在720*1280分辨率下进行设计,此分辨率下1dp=2px.
可以直接使用dp标注尺寸,sp标注文字大小

注:使用dp标注尺寸。使用sp标注文字大小

该使用什么字体及字号?
中文字体:思源
英文字体:Android 4.x及以上采用Roboto,Android 2.x和3.x采用Droid Sans.
字号:12sp、14sp、18sp、22sp(也可根据实际情况调整)

目前掌握以上知识点,可能多少也有些小问题,欢迎有经验的大神指正、指导。谢谢啦~

⑥ android屏幕适配做哪几个尺寸

android屏幕适配尺寸有全屏模式、4:9、8:12多种。

android屏幕适配尺寸有多种,具体的要结合自己的兴趣爱好和手机的自身的实际情况,具体设置标准如下:

1、不要使用绝对布局,这会限制你的手机屏幕的更换。

2、尽量使用match_parent ,从而保证屏幕的最大化利用。

3、尽量使用权重(android:layout_weight),保持手机屏幕合理布局。

4、尽量使用android的shape 自定义,形成纯色背景。

5、可以在res目录上新建layout-HxW.xml的文件夹进行在特定分辨率下适配。


拓展资料:

由于笔记本电脑采用的液晶屏的大小和分辨率是根据它的市场定位决定的,所以为了适应不同人群的消费能力和使用习惯,笔记本电脑的液晶显示器的尺寸和分辨率种类远远要比台式液晶显示器多。

⑦ 怎么样让Android实现全屏幕适配

一、关于布局适配

1、不要使用绝对布局

2、尽量使用match_parent 而不是fill_parent 。

3、能够使用权重的地方尽量使用权重(android:layout_weight)

4、如果是纯色背景,尽量使用android的shape 自定义。

5、如果需要在特定分辨率下适配,可以在res目录上新建layout-HxW.xml的文件夹。比如要适配1080*1800的屏幕(魅族MX3采用此分辨率)则新建layout-1800x1080.xml的文件夹,然后在下面定义布局。Android系统会优先查找分辨率相同的布局,如果不存在则换使用默认的layout下的布局。

二、关于图片制作

1、关于设计:

设计图先定下一个要设计的尺寸,而且尽量采用在目前最流行的屏幕尺寸(比如目前占屏幕比重比较多的是480系列,也即是480*800或者400*854,下面的图标制作也在次基础上进行比例的换算)上设计。

先了解一下屏幕的级别:

屏幕级别:

注意屏幕级别是按照密度分级,和像素没有关系。如果非要让密度和像素扯上关系,则需要一个参照系,android使用mdpi级别作为标准参照屏幕,也就是说在320*480分辨率的手机上一个密度可以容纳一个像素。然后其他密度级别则在此基础上进行对比。如果理想情况下,480*800的屏幕一个密度可以容纳1.5个像素。

物理大小:

单位是英寸而不是像素,也就说一个英寸在任何分辨率下显示的大小都是一样的,但是像素在密度不同的手机里面显示的实际的大小是不一样的(这就是为什么android手机需要适配的原因)。

然后就是重点。

假设1像素在160密度下显示1英寸,则1像素在240密度基础上显示大约0.67英寸,在320密度下显示0.5英寸。于是就出现一种情况,在电脑上的一个像素,在不同的手机上看实际的大小不一样。那么怎么让“设计效果”在不同的手机上看起来显示的区域一样呢?

还是假设一个像素在160密度下的显示在一个密度内,也假设就是一英寸。那么需要几个像素才能在240密度级别下显示在一英寸范围内呢?答案是1.5个像素(根据上图的比率换算)。

了解了这个关系,接下来就是图标的制作。

2、关于切图。

关于切图有几个建议:

第一,长宽最好是3的倍数(根据android的推荐logo图标的大小是48(mdpi),72(hdpi),96(xhdpi)得出的最小公约数)。

第二,长宽最好是偶数。因为奇数在进行等比压缩的时候可能有问题。

第三,根据上面两条,如果长宽是6的倍数最理想。

第四,如果可以拉伸而不改变设计意图的情况下,比如纯色背景,则使用android的9path工具制作成.9的图片。

3、关于图标的适配。

然后接下来的一切就和设计稿没什么关系。在切好图的基础上,根据屏幕密度、像素和实际大小的比例关系。假如设计司在480*800的分辨率下做好了设计图,并且切好图,如果你需要适配720*1280屏幕,该怎么做?根据比例,他们的关系是2:3,于是你需要按照1.5倍比例制作图标,比如你在480*800的设计稿上切下来一个20*20像素的图,那么你就需要制作一个等比放大成30*30像素的图标,这样同一个图标在480*800的屏幕和720*1280的屏幕上显示的实际大小才一样。同理,如果你需要适配xxhdpi则需要在20*20的基础上制作一个等比放大成40*40像素的图标。

4、关于图标的目录,480*800切下来的图我们放在drawable-hdpi目录下,按照2:3放大的图标放在drawable-xhdpi目录下,按照2倍放大的图标放在drawable-xxhdpi目录下。

android会根据手机的密度优先查找对应的目录的资源,

比如408*800分辨率下的手机如果密度是160,则自动加载drawable-hdpi这个目录下的图标,

如果720*1280密度是240的手机自动加载drawable-xhdpi这个目录下的图标。如果没有这个文件夹,则查找和240最接近的对应密度文件夹。

三、其它

接下来要说的估计会让你失望,根据上面的步骤也不能完全解决适配的问题,只能是大概适配,而就算根据上面的步骤大概适配了,实际在手机上的效果也有出入。

比如魅族MX3的分辨率是1080*1800,标准情况下密度是480,但是他的密度大约是524,和480接近,也就是会查找drawable-xxhdpi这个资源下的文件。也就是说你在480*800分辨率下切图然后按两倍放大的图标在这台手机上显示的效果还是比实际的小。

而另一个要说的问题是540*960或者640*960,他们的密度很可能是或者接近240也可能是320。于是在480*800的设计稿上切下来的图并且进行的适配制作,在这些手机上显示的实际大小也可能或大或小。

⑧ 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也变小了。

⑨ 屏幕适配那些事(02)Android逻辑像素刨根问底

屏幕适配是一个老生常谈的问题了,我用这三篇博客和大家讨论点屏幕适配相关的干货。

iOS的屏幕规格可以列举处理,iPhone4及更新的设备,只有4种规格,他们的逻辑分辨率像也是固定的。Android这边就比较复杂了,理论上可以出现无数种逻辑分辨率。Android的逻辑分辨率可以通过三个步骤推导得到:

以Nexus 5为例:

你可能会问,按照上面的推导,屏幕像素密度越低(像素分辨率相同,尺寸越大),逻辑分辨率应该越高。但是上一节讨论中,为什么说“三星S7和三星S7 edge,屏幕尺寸分别为5.1和5.5英寸,但是他们显示的内容是一样多的(逻辑分辨率一致)”?

是的,显然S7和S7 edge的屏幕像素密度是不同的(尺寸不同但是像素分辨率一致),但是为什么逻辑像素密度会一样呢?下面进行解释:

Android SDK 中:

我们可以总结出一个 结论:Android设备,虽然屏幕分辨率不同,但是通常相同大小屏幕的设备具有相同的逻辑分辨率。

有什么指导意义呢?Android设备虽然有数不清的屏幕规格,但是逻辑分辨率的规格就没有那么多啦,而且可以方便的找到几个参考值:360×640(大部分720P及以上手机屏幕)、411×731(部分2K屏幕)等,基准设计稿就可以参考这些值啦。

下一篇文章给出一点我对屏幕适配的建议。

阅读全文

与android屏幕尺寸适配相关的资料

热点内容
dvd光盘存储汉子算法 浏览:757
苹果邮件无法连接服务器地址 浏览:963
phpffmpeg转码 浏览:672
长沙好玩的解压项目 浏览:145
专属学情分析报告是什么app 浏览:564
php工程部署 浏览:833
android全屏透明 浏览:737
阿里云服务器已开通怎么办 浏览:803
光遇为什么登录时服务器已满 浏览:302
PDF分析 浏览:486
h3c光纤全工半全工设置命令 浏览:143
公司法pdf下载 浏览:382
linuxmarkdown 浏览:350
华为手机怎么多选文件夹 浏览:683
如何取消命令方块指令 浏览:350
风翼app为什么进不去了 浏览:778
im4java压缩图片 浏览:362
数据查询网站源码 浏览:151
伊克塞尔文档怎么进行加密 浏览:892
app转账是什么 浏览:163