Android手机屏幕适配一直是老生常谈的问题,像Android产品市场上种类繁多,单单就手机而言,屏幕的尺寸和分辨率就各有不同,还包括搭载Andorid系统的平板、穿戴设备、电视、车机等产品,要想自己做的APP能够自由地运行在各种设备上,适配那是必须的。
1.屏幕尺寸、屏幕分辨率、屏幕像素密度
(1)屏幕尺寸
买手机时最常见,目前Android手机都开始向大屏方向发展,像过往的5.0英寸的手机,都成小屏幕手机了,常见的5.0英寸、5.15英寸、5.5英寸等,都是屏幕尺寸,对于屏幕尺寸的适配,没有太多的要求。
(2)屏幕分辨率
目前市面上最常见的就是1080P,1920*1080,单位是px,1px = 1像素点,这也是1080P的由来,P就是px,横纵的像素个数乘积。
(3)屏幕像素密度
指的是每英寸屏幕上像素点的个数,单位是dpi,这个参数在买手机的时候也是会带的,尤其是大屏手机,如果屏幕像素密度比较低,就会有颗粒感,不知你们有没有这样的体验。
2.dp、dip、dpi、sp、px等计量单位之间的关系
(1)dp和dip
这个就非常常见了,我们在写布局的时候,在设置控件宽度或者高度的时候,都会设置为xxdp;以160dpi(屏幕像素密度)为基准,1dip = 1px
dp(dip)是密度无关像素,为什么这么说呢?
假设有两个手机屏幕,分别为A:480320(160dpi)和B:800480(240dpi)
在手机屏幕上画一条线,是A的屏幕宽度,那么是320px,在设置了320px之后,放在了B手机上,就不是B手机屏幕的宽度了,B的手机宽度是480px,还差了一截呢!
但是使用密度无关像素之后,就不同了,在A手机画手机屏幕的宽度的直线是320dp,因为160dpi为基准,1dp= 1px,所以是320px;那么到了B手机上后,320dp的长度在240dpi的分辨率上(1dp = 1.5px),那么长度就是320*1.5 = 480px,完美适配B手机的屏幕,也是跟B的屏幕宽度一致。
(2)sp
在设置字体大小的时候,通常会使用sp,在设置sp的大小时,最好使用偶数,不要使用奇数。一般是12sp、14sp、18sp、22sp
3.什么是mdpi、hdpi、xdpi、xxdpi
因为不同的手机屏幕,有不同的屏幕像素密度,一张图片在不同的屏幕像素密度上呈现出来的状态是 不一样的,所以需要根据不同的像素密度,来配置不同的图片。
名称 | 像素密度范围 |
---|---|
mdpi | 120-160dpi |
hdpi | 160-240dpi |
xhdpi | 240-320dpi |
xxhdpi | 320-480dpi |
xxxhdpi | 480-640dpi |
在做图片处理的时候,mdpi是基准,因为它的像素密度在160以下,1dp = 1px,所以可以根据mdpi的图片尺寸做尺寸放大,在hdpi可以在mdpi的基础上放大1.5倍,xhdpi放大2倍,xxhdpi放大3倍,xxxhdpi方大4倍。
4.屏幕适配要完成的目标
(1)支持各种屏幕尺寸
--------wrap_content、match_parent、weight
wrap_content、match_parent是最常用的,在设置控件的长和宽的时候使用,wrap_content:包裹其自身,根据内部的大小来设置自身的大小,match_parent:与父容器相同,跟屏幕的宽度或者高度,或者剩余空间的宽度和高度一致。
android:layout_width="match_parent"
android:layout_height="match_parent"
weight:权重,是线性布局中的一个属性,通常来设置其占据的空间大小,例如有3个控件,平分屏幕的宽度,则每个权重设为1;或者说,3个控件,其中1个控件占据除了另外2个控件的剩余空间,则将这一个控件的weight设置为1就可以了。
weight的计算方式:假设2个控件去分屏幕的宽度,那么可以给他们设置比例,1:2或者1:3,那么假设是1:2
控件1:宽度 match 高度wrap 控件2:宽度 match 高度wrap
计算公式:原来的宽度+剩余空间所占百分比的宽度
拿控件1来说,原来的宽度就是屏幕的宽度,假设是M,剩余的空间是总的宽度 - 控件1和控件2的总宽度(屏幕宽度M - 总宽度2M)= - M*1/3(比例),最终得出的宽度是2/3M,控件1占据2倍的空间。比例是2:1
总宽度为什么是2M:因为控件1和控件2的宽度都是match
还有一个是0dp的情况,假设:(比例是1:2)
控件1:宽度 0 高度wrap 控件2:宽度 0 高度wrap
那么控件1的宽度是0,剩余空间就是M - 20 = M1/3 = 1/3M,那么最终的比例就是1:2
--------使用相对布局,禁用绝对布局
在使用相对布局时,因为会涉及到很多位置关系
android:layout_alignLeft="@id/tv_subject"
android:layout_below="@id/tv_subject"
android:layout_marginTop="10dp"
android:layout_marginRight="130dp"
这样无论是在手机,还是在平板都能很好地适配他们之间的相对关系。
--------使用限定符
large限定符、最小宽度限定符
在之前的章节中也说到,除了手机,还有平板等搭载Android系统的设备,当适配到平板上时,我们希望的是不会出现变形的状况,因此出现了这两种限定符。
在Android3.2之前采用的是large限定符,在3.2之后,主流的就是最小宽度限定符,我们在设计时的双面板,当系统检测到平板它的最小宽度限定符之后,会自适应选取双面板布局。
但是在使用这两种限定符的时候,我们需要做两套布局,比较费时费力,有没有解决方案,减少过多的工作
--------使用布局别名
res/layout/main.xml:手机布局
res/layout-large/main.xml:Android3.2之前的平板布局
res/layout-sw600dp/main.xml:Android3.2之后的平板布局
--------使用屏幕方向限定符
还是在适应手机和平板上使用
--------使用自动拉伸位图
自动拉伸位图,就是.9图或者9-patch图片
(2)支持各种屏幕密度
-----使用各种密度无关像素dp、dip、sp等
场景:假设一个手机屏幕宽度为360dp,一个Button1宽度为150dp,另一个Button2宽度为200dp,紧贴手机右侧屏幕,这样放在手机屏幕上,按道理说应该是中间留有10dp的空间,但是放在不同分辨率和尺寸的手机上,显示的效果是不一样的,有的中间几乎没有空间,有的中间拉扯的很大,这是什么原因?
我们在使用dp、dip时可以适配屏幕像素密度的问题,以160dpi为基准,进行等比例的缩放。但是在使用dp时跟它有关联的只有像素密度,跟屏幕的尺寸大小并无关系,所以才出现这样的问题,假设一个360dp宽度的手机,他们的dpi不同,那么最终显示的结果也是不同的。
假设手机A和手机B的dpi都是160,但是A宽度320dp,B是480dp,那么在A手机上Button1宽度是150dp,Button2宽度是200dp,那么在B手机上也是Button1宽度是150dp,Button2宽度是200dp,那么中间就隔了130dp,而不是A手机的10dp。
所以避免这种情况就是不要把宽度定死了,使用wrap_content或者match_parent就可以了。
那还有没有其他方法去解决这个问题呢?
-----解决手机屏幕宽度不一致的问题
不使用dp和dip,自己约定一个长度计量单位,假设一个手机A宽度是320dp,也就是320px;一个手机B的宽度是480dp,也就是480px;一个手机C的宽度是640dp,也就是640px。三个手机都是160dpi,也就是说1dp = 1px,这时候使用dp就会出现手机屏幕宽度不一致的情况。
那么解决的方案就是,自己约定一个长度计量单位,假设是lp,这个lp以手机屏幕为基准,假设手机屏幕是320dp宽度,那么将这个宽度平均分成320分,1lp = 1dp = 1px;如果传入的手机屏幕是480dp,那么同样的也是分为320份,那么1lp = 1.5dp = 1.5px;如果传入的手机屏幕是640dp,那么同样分成320份,那么1lp = 2dp = 2px。可以看出这个lp是动态变化的,是以屏幕的宽度动态变化的。
当在手机A画一段150lp的直线,就是150dp,那么适配在B上,就是1501.5dp(注意不是因为dpi而等比例扩大,而是因为屏幕,要注意区分),适配在C手机上,就是1502dp,如此以来,在开篇所讲的关于屏幕大小不一致而导致的空间分布不均的问题,就解决了。
总结:我们在使用dp或者dip可以完美适配屏幕像素密度不同,而与屏幕宽度无关;使用lp则是可以解决因为屏幕宽度不同而出现的问题,可以灵活使用。
------提供多套位图
在使用位图时,我们通常会根据屏幕像素密度来做多套图来适配不同的机器,但是这个会带来比较大的内存开销;当我们把一张图片放到手机像素密度是xxhdpi范围的drawable-xxhpi的目录下时,占用的内存开销大概是10几M,但是如果放在drawable目录下,直接飙升到接近80M,这对于内存极为宝贵的Android手机来说,是极为致命的。同时放在其他像素密度的文件夹下依然和drawable目录一样。
所以在做图片时,不要把高分辨率的图片放在不同的分辨率目录下,这样因为不同分辨率的拉伸,会导致内存的急剧增长;所以要做不同分辨率的图片,放在不同的分辨率下才是正确的做法。
来源:CSDN
作者:那年1月26日那一天
链接:https://blog.csdn.net/qq_33235287/article/details/104187382