[Android 总结] 屏幕适配方案 续

2018-07-27  本文已影响0人  graychen

接着上一篇的《屏幕适配方案》,上一篇讲了dp 的作用,接下说下其他的真实适配方案。

2.宽高限定符适配

所谓宽高限定符适配,就是在资源文件下生成不同分辨率的资源文件,然后在不同的分辨率下生成不同的dimens


根据分辨率不同生成不一样的资源文件

设定一个基准的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件

比如以1080*1920为基准分辨率,其他的根据这个基准换算出相应的值放在目标文件下。

假设一张图片在这个分辨率下的大小为180*180,那么我们的宽高可以这样写

android:layout_height="@dimen/px_180"    android:layout_width="@dimen/px_180" 

在“values -1080x1920” 这个资源文件下 :

<dimen name="px_180">180px</dimen>

那么对于720*1280的分辨率的手机来说,换算的结果就是

宽为:180/(1080/720) = 180/1.5 = 120 px

高为:180/(1920/1280) = 180/1.5 = 120 px

所以:在values -720x1280 这个资源文件下" px_180 "为 :

 <dimen name="px_180">120px</dimen> 

    这样,我们的UI设计界面使用的就是基准分辨率设计,那么我们就可以按照设计稿上的尺寸填写相对应的dimens引用了,而当APP运行在不同分辨率的手机中时,这些系统会根据这些dimens引用去该分辨率的文件夹下面寻找对应的值。这样基本解决了我们的适配问题,而且极大的提升了我们UI开发的效率。理论上只要不同分辨率下资源文件齐全,那么我们的页面就是适配所有的手机了。

    其实这也就是这种适配方案的缺点了!我们需要知道市场上所有分辨率的手机,并且一一为他们写资源文件。比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差,而且不宜于维护,每改一个值要所有的资源文件都修改

3.UI适配框架AutoLayout

    这个框架是我之前采用过的一种适配方式,是鸿洋大佬写Layout 适配方案,github地址 AndroidAutoLayout

目前项目已经停止维护了,这里贴下博客《Android AutoLayout全新的适配方式 堪称适配终结者》。

第一步:

在你的项目的AndroidManifest中注明你的设计稿的尺寸

标识自己的设计稿尺寸

第二步:

让你的Activity继承自AutoLayoutActivity.

     然后我们就可以直接在布局文件里面使用具体的像素值了,比如,设计稿上是96*96,那么我们可以直接写96px,APP运行时,框架会帮助我们根据不同手机的具体尺寸按比例伸缩。这可以说是一个极好的方案,因为它在宽高限定符适配的基础上更进一步,并且解决了容错机制的问题,可以说完美的达成了开发高效和适配精准的两个要求,框架要在运行时会在onMeasure里面做变换,我们自定义的控件可能会被影响或限制,可能有些特定的控件,需要单独适配。

    这种方案的好处是不用再 为多种分辨率写多个dimens了,再也不用去计算百分比了,也不用再跟UI扯皮说dp的是事情了,但是目前该框架已经停止维护了。

4.smallestWidth 限定符适配方案

我个人觉得 smallestWidth 限定符屏幕适配方案 是宽高限定符屏幕适配方案的升级版。因为 smallestWidth 限定符屏幕适配方案 只是把 dimens.xml 文件中的值从 px 换成了 dp,原理和使用方式都是没变的。如下图:

    其实smallestWidth 限定符屏幕适配方案的原理也很简单,开发者先在项目中根据主流屏幕的最小宽度 (smallestWidth)生成一系列values-sw<N>dp文件夹 (含有dimens.xml文件),当把项目运行到设备上时,系统会根据当前设备屏幕的最小宽度 (smallestWidth)去匹配对应的values-sw<N>dp文件夹,而对应的values-sw<N>dp文件夹中的dimens.xml文字中的值,又是根据当前设备屏幕的最小宽度 (smallestWidth)而定制的,所以一定能适配当前设备

    如果系统根据当前设备屏幕的最小宽度 (smallestWidth)没找到对应的values-sw<N>dp文件夹,则会去寻找与之最小宽度 (smallestWidth)相近的values-sw<N>dp文件夹,系统只会寻找小于或等于当前设备最小宽度 (smallestWidth)values-sw<N>dp,这就是优于宽高限定符屏幕适配方案的容错率,并且也可以少生成很多values-sw<N>dp文件夹,减轻App的体积。

   注意这里不是宽度,而是最小的那一边的宽度。,我们的手机或者平板设备是可以旋转的,当横屏切换时屏幕的高宽也会互换。这里最小宽度就是不区分屏幕方向的,它只会把屏幕的高度和宽度中值最小的一方认为是最小宽度,这个最小宽度是根据屏幕来定的,是固定不变的,所以不管怎么旋转,系统只认定最小的那一边为最小宽度

    如果想让屏幕宽度随着屏幕的旋转,就是旋转后适配不同的资源文件呢,可以再根据values-w<N>dp(去掉sw中的s) 生成一套资源文件,比如

values-w1080dp     values-w1920dp  

这样,当竖屏的时候手机宽度为1080的就会使用values-w1080dp 文件下的值,当横屏了宽度变为1920了,系统就会使用values-w1920dp 文件下的值。

  如果想区分屏幕的方向来做适配该怎么办呢?那就只有再根据屏幕方向限定符生成一套资源文件咯,后缀加上-land-port即可,像这样,values-sw720dp-land (最小宽度 720 dp 横向)values-sw1920dp-port (最小宽度 1920 dp 纵向)

smallestWidth的计算规则

    如果想在程序上直接运行跑出结果可以这样用:

Configuration config = getResources().getConfiguration();

int smallestScreenWidth = config.smallestScreenWidthDp;

同宽高限定一样,不同最小宽度下的,以一个为基准,按比例算出其他的值。比如,我以1080dp为基准如下图:

values-sw720dp-land下的基准值 values-sw720dp-land 下的根据1080按比例换算出来的

    目前 这套方案也是我比较常用的,个人觉得比较完美的适配方案了。从开发效率上,它不逊色于上述任意一种方案。根据固定的放缩比例,我们基本可以按照UI设计的尺寸不假思索的填写对应的dimens引用。一上面的两个图为例,我在values-sw1080dp文件夹下的diemns文件意味着手机的最小宽度的dp值是1080,然后我的设计稿也是以1080像素的手机设计的,我就以他为基准,每个设计稿中像素是多少我就在values-sw1080dp 填写相同是值就可以,如果是sw720dp的手机,1080刚好是720的1.5倍,那diemns里面的值也是除以1.5就可以了。

    不过smallestWidth适配方案有是在Android 3.2 以后引入的,,不过目前所有的项目应该最低支持版本应该都是4.0了

上一篇下一篇

猜你喜欢

热点阅读