您当前的位置:首页 > 互联网教程

Android屏幕适配-应用篇

发布时间:2025-05-16 06:41:43    发布人:远客网络

Android屏幕适配-应用篇

一、Android屏幕适配-应用篇

从两个大方面阐述一下Android的屏幕适配:

  Android推荐使用dp作为尺寸单位来适配UI,通过dp加上自适应布局和weight比例布局可以基本解决不同手机上适配的问题,这基本是最原始的Android适配方案。

(1)这种方案只能保证我们写出来的界面适配绝大部分手机,部分手机仍然需要单独适配,但dpi的不同,还是会存在差异。

(2)一般的设计稿都是以px为单位的,所以我们在写layout文件的时候需要将px转为dp,影响开发效率。

 为了高效的实现UI开发,出现了新的适配方案,我把它称作宽高限定符适配。简单说,就是穷举市面上所有的Android手机的宽高像素值,设定一个基准的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件:

鸿洋大神的作品,使用也超级简单,核心功能就是在绘制的时候在onMeasure里面做变换,重新计算px。

缺点:我们自定义的控件可能会被影响或限制,可能有些特定的控件(框架没有做适配的控件),需要单独适配。

  小结:上述几种适配方案都是实际开发中用过的方案,但随着技术不断的更新,出现了更好的适配方案。

  实现原理:Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。

   sw限定符适配和宽高限定符适配类似,区别在于,前者有很好的容错机制,如果没有value-sw360dp文件夹,系统会向下寻找,比如离360dp最近的只有value-sw350dp,那么Android就会选择value-sw350dp文件夹下面的资源文件。这个特性就完美的解决了上文提到的宽高限定符的容错问题。

  优点: 1.非常稳定,极低概率出现意外

    2.不会有任何性能的损耗

    3.适配范围可自由控制,不会影响其他三方库

  缺点:就是多个dimens文件可能导致apk变大,几百k。

  附件:生成sw文件的工具

  实现原理:修改系统的density值(核心)

  今日头条适配是以设计图的宽或高进行适配的,适配最终是改变系统density实现的。

  AndroidAutoSize是基于今日头条适配方案,该开源库已经很大程度上解决了今日头条适配方案的两个缺点,可以对activity,fragment进行取消适配。也是目前我的项目中所使用的适配方案。

(2)在 AndroidManifest中填写全局设计图尺寸(单位 dp),如果使用副单位,则可以直接填写像素尺寸,不需要再将像素转化为 dp,详情请查看 demo-subunits

二、关于Android界面适配的思考及最终解决方案

1、一直以来都用 px映射表来解决不同界面的适配性问题(参考: Android界面开发精要1:尺寸)。最近在一些设备上发现,这种方案也有弊端:以UI图的基础设计是基于720*1280(如Galaxy Nexus)为例,最近发现有些设备的像素宽高比并不是如此,比如Nexus 4就是768*1280。

2、这种情形下,不同的映射方式会有不同的效果:

3、仔细思考就会发现问题的本质是:控件宽高计算基准是不同的。

4、这让我想起iOS开发中,其界面设计系统AutoLayout,就采用了一个计算公式:

5、也就是说,任何控件都可以以其他控件的属性值来定义自身的属性值,所以其可塑性非常高。不过实际应用中也会带来一个问题,就是太灵活,导致多重约束,有时候会彼此冲突。

6、仔细想想,最常见的视角参数应该就只有3个:

7、透过这3个参数,应该可以定义任意控件的属性值。

8、现在问题来了,Android怎么做到呢?答案是:**** android-percent-support-extend****

9、对于值可以取:10%w, 10%h, 10%, 10%sw, 10%sh,缩写含义为

10、对于一开始的界面,最后xml文件为:

11、这种直接裸写百分比的方式比价繁琐,相较之下,目前采用 px映射表的方案中写的px值直接在UI设计图中取就行,更加简单。

12、其实px映射表方案也就是百分比的方案,而且x值和y值已经分开,所以也可以解决正方形变形的问题。

13、目前需要客服的问题主要在于px映射为px,导致如果没有覆盖到设备的分辨率,就会出现问题,改成px映射为dp后,这种问题应该会减少很多。

三、Android 开发中 如何做到XML多屏幕适配

Android上面解决适配不同尺寸(分辨率)和密度的问题,主要是通过以密度分类,再加上分辨率的方式来减化适配不同尺寸屏幕的工作量.

一般来讲,屏幕分辨率越高,清晰度也应该越高,也即其密度也应该越大,否则会看起来很不清楚,比如4寸的屏幕只显示100个像素,这就近距离看电影,或者看投影仪一样,非常的粗糙和不清晰.所以,Android主要是以屏幕密度来区分不同的设备:

高密度: hdpi(High dots per inch)

中等密度: mdpi(Medium dots per inch)

低密度: ldpi(Low dots per inch)

并且布局中推荐使用密度无关单位dip或dp,来作为长度或者宽度的单位.这样,从理论上来讲,开发者只需要做:

1.为不同的密度屏幕准备图片资源

(图片是没办法的,因为图片的长度和宽度是固定的像素值,不能够随密度变化而变化,可以强行拉伸,但图片会失真.当然也有9 Patch图片可以解决随意拉伸的问题.但普通的图片的长度和宽度是固定的.

2.用dip作为单位来指定长度或者宽度

就可以适配所有的设备,让布局在所有的屏幕上都得到比较好的显示效果.

当然,现实的生活没有这么完美,各种设备千差万别.但是总体仍可分为这三大类,为这三大类准备好图片后,其他的只要与某一类较接近,即使稍有拉伸或失真,也不太明显,是可以接受的.所以,对于一般性的应用程序,写一个布局文件在layout中,为三种密度准备图片drawable-hdpi, drawable-mdpi, drawable-ldpi,就足以应对80%的设备.

(这里可能有点过时了,因为现在多了xdpi,而且很多设备也是xdpi的.)

但是光以密度屏幕来分类和处理还不够.随着设备的越来越多,以及屏幕尺寸越来越大,还有就是Tablet的出现,又会出现这样的问题:设备的屏幕密度虽然不高,但其分辨率很高.举个简单的例子:iPad2的分辨率是1024x768,iPhone 4 960x640,但是iPhone 4的密度是326ppi,远大于iPad2.但是,无论密度有多高它的屏幕就那么,最多能显示960x640个像素点,一个1024*768的图片在iPad上可以看到全部,而iPhone上只能看到一大半!这也是为什么用iPad来运行iPhone上的应用程序时,只是以屏幕中间的一部分来模拟显示的原因.

对Android来说也是一样的.如此一来,即使相同的dpi,假如其屏幕尺寸非常大,那么为其准备的图片将被拉伸很大或者显示不全.UI元素也会被拉伸很长.这样并不是很好的体验.对于尺寸大的屏幕应该让其显示更多的内容,而不是把一部分元素拉伸很大.所以,很多手机安卓应用如果未经专门适配,在平板上直接使用体验将会是非常差的.

为了解决这样的问题,就还必须以屏幕尺寸来区分设备

主要有四种屏幕尺寸:small, normal, large and xlarge

这主要是配合屏幕密度来一起使用,比如,适配平板的图片:

drawable-xlarge-hdpi/ic_launcher.png

这里就要提到了密度,尺寸和分辨率的对应关系了.屏幕分辨率是随设备变化最明显的一个,上面的二种分类方法仅是对屏幕进行的大致的一个分类.虽然屏幕分辨率与密度没有直接的关系,但是所有的设备都基本上一致的: