Android方案需求,Android 三种适配方案

适配缘由

做Android开发一定会碰到适配这个问题,在Android世界里,Android设备太多了,手机,平板,TV,手表等,光其中的手机这一项就有众多厂家发布的奇奇怪怪的手机,不仅分辨率各有不同,就是手机尺寸也是一言难尽,各种尺寸都有,更烦的是有的手机还在屏幕上搞个虚拟导航栏放在底部;厂家多也就算了,由于Android系统的开源,任何厂家,个人,OEM厂商,运营商都可以对Android进行定制,修改成他们想要的样子,这更加大了适配的难度(尤其是我在平时开发中经常会用到一些工程机);总之而言,Android的碎片化太严重了;不像ios适配机型有限,所以解决掉Android适配问题是做一个好的APP的第一步

相关概念

在开发过程中,UI给出的设计图上的所有元素尺寸都是以px作为单位的,但是我们在layout文件中定义相关View的长宽是用dp作为单位来指定其值的,定义文字大小是用sp作为单位,还可能会涉及到屏幕尺寸,屏幕分辨率,屏幕像素密度dpi

这里说到了四个单位:px dp sp dpi,还有屏幕尺寸及屏幕分辨率:

屏幕分辨率:指手机横纵方向上的像素点数,比如常见的720 * 1280 ,1080 * 1920,单位px,1px=一个像素点,

屏幕尺寸:不是屏幕宽度,也不是长度,而是屏幕的对角线长度,比如常见的5.0尺寸,5.5尺寸,单位是英寸,1英寸=2.54厘米

dpi:全称dots per ich,也就是每英寸的像素点数(其实不是真正有多少像素点数),或者说屏幕像素密度;它是一个软件上的概念,是在系统软件上指定的单位尺寸的像素数量,它往往是写在系统出厂配置文件的一个固定值;我们可能还接触过一个单位叫ppi,它也是像素密度,这个是物理上的概念,它是客观存在的不会改变。dpi是软件参考了物理像素密度后,人为指定的一个值,这样保证了某一个区间内的物理像素密度在软件上都使用同一个值。这样会有利于我们的UI适配;比如,几部相同分辨率不同尺寸的手机的ppi可能分别是是430,440,450,那么在Android系统中,可能dpi会全部指定为480;ppi与屏幕尺寸和屏幕分辨率有关,它们的关系如下

math?formula=dpi%20%3D%20%5Cfrac%7B%5Csqrt%7B%20x%5E2%20%2By%5E2%7D%7D%7B%E5%B1%8F%E5%B9%95%E5%B0%BA%E5%AF%B8%7D%20

px:这个大家容易理解,也就是真实像素的单位,就跟s是时间秒的单位一样

sp:全称scale-independent pixel,也叫sip,即独立缩放像素,Android特有的用来描述文字大小的单位,建议使用12,14,18,20等偶数值,避免奇数和小数造成精度的丢失问题;为什么用这个不用dp呢?这是因为我们可以在手机系统设置中修改文字的大小,如果使用dp单位,文字大小不会被改变;而使用sp会随着修改而变化;具体原因可参考sp与dp的区别

dp:全称Density-independent pixel 也叫dip,即独立像素密度,它的一个特性就是与像素无关,或者说与终端上的实际物理像素点无关,是Android特有的用来描述View尺寸的单位,保证同一个分辨率的图片在不同分辨率的手机上保持同样的视觉大小(占用相识比例的空间)

比如同样都是画一条长度是屏幕一半的线,如果使用px作为计量单位,那么在480x800分辨率手机上设置应为240px;在320x480的手机上应设置为160px,二者设置就不同了;如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度,原因在下方

在Android中,规定以160dpi为基准,1dp=1px;320dpi下,1dp = 2px,计算公式:px = dp * (dpi / 160),屏幕密度越大,1dp对应 的像素点越多,如下表

37f6d4ca1180

这里还有一个东西没有提,mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi等,它们是用来修饰Android中的mipmap(Eclipse中是drawable)文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值,它们与dpi的关系如下

37f6d4ca1180

屏幕分辨率限定符

什么叫屏幕分辨率限定符呢?

我们知道市面上不同分辨率的手机太多太多了,而这种方案就是尽可能多的将其列举出来,在res目录下面创建与各种分辨率一一对应的values-xxx 文件夹;然后选定一种基准分辨率,然后其它分辨率以该分辨率做参考,生成对应的dimens文件,如图:

37f6d4ca1180

假设设计图上的一个控件的宽度为 720px,那么布局中就写 android:layout_width="@dimen/x720" ,当运行程序的时候,系统会根据设备的分辨率去寻找对应的 dimens.xml 文件。例如运行在分辨率为 1280x720 的设备上,系统会自动找到对应的 values-1280x720 文件夹下的 lay_x.xml 文件,由上图可知 x720 对应的值为

720.px,可铺满该屏幕宽度。运行在分辨率为 1920x1080 的设备上,系统会自动找到对应的 values-1920x1080 文件夹下的 lay_x.xml 文件,由上图可知 x720 对应的值为 1080.0px,可铺满该屏幕宽度。这样就达到了屏幕适配的要求

使用步骤

1、以设计图最小宽度(单位为 dp)作为基准值,生成所有设备对应的 dimens.xml 文件

这些文件当然不会手动去写,网上已经有大神提供了自动生成这些文件的插件ScreenMatch。但是这个插件还是有点问题的:

默认没有适配最小宽度为 320dp 的设备。其实自己测试还是有很多设备最小宽度是 320dp 的,所以需要加上。

最小宽度为 392.7272 与 411.4285 的手机不能达到完全适配。原因是该插件的默认值都是取整的,即 392.7272 与 411.4285 在插件中写的是 392 与 411。

基于以上问题,我在该插件的源码上优化生成了新的插件ScreenMatch,由于插件库已经有原作者的插件了,所以我就不重复造轮子上传到插件库了,你直接用本地安装的方式安装即可。

工具使用步骤:

在 Android Studio 中安装 ScreenMatch 插件

下载插件ScreenMatch到本地,点击菜单栏上的 File -> Settings -> Plugins -> Install plugin from disk,然后选择我们刚刚下载的插件,最后点击 “OK”,重启 Andorid Studio 即可。如下图所示:

37f6d4ca1180

2、在项目的默认 values 文件夹中需要一份 dimens.xml 文件

3、执行生成

插件安装好后,在项目的任意目录或文件上右键,选择 ScreenMatch 选项。如下图:

37f6d4ca1180

4、通过上面的步骤就已经生成了所有设备对应的 dimens.xml 文件。

根据设计图填写最小宽度基准值,并填写需要适配的设备最小宽度 dp 值

步骤 3 是以插件默认的最小宽度基准值为 360dp,适配的设备最小宽度为

320,360,384,392.7272,400,410,411.4285,432,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365(包含了平板和 TV )生成的文件,但实际情况要根据设计图和需求设置。

例如设计图的最小宽度为 375dp,则需要更改最小宽度基准值为 375dp。如果项目只需要适配手机的话,适配的设备最小宽度保留 320,360,384,392.7272,400,410,411.4285,432,480 即可,若发现手机还有其他最小宽度自行加上即可,也麻烦把该最小宽度提供给我,我们一起来完善该份适配。

以上修改需要在配置文件里修改,即 screenMatch.properties 文件,该配置文件是执行完上面第 3 步后自动生成在项目的跟目录下的。如下图:

37f6d4ca1180

AutoLayout适配

用法

(1) 引入autolayout

```

dependencies {

compile project(':autolayout')

}

```

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

```

<

meta-data android:name="design_width" android:value="768">

```

(2)Activity中开启设配

让你的Activity去继承AutoLayoutActivity

今日头条适配方案(AutoSize)

使用步骤

1、添加依赖

```

api 'me.jessyan:autosize:1.1.2'

```

2、填写项目设计图尺寸

```

```

有两种类型的布局单位可以选择,一个是 主单位 (dp、sp),一个是 副单位 (pt、in、mm)

主单位: 使用 dp、sp 为单位进行布局,侵入性最低,会影响其他三方库页面、三方库控件以及系统控件的布局效果,但 AndroidAutoSize 也通过这个特性,使用 ExternalAdaptManager 实现了在不修改三方库源码的情况下适配三方库的功能

副单位: 使用 pt、in、mm 为单位进行布局,侵入性高,对老项目的支持比较好,不会影响其他三方库页面、三方库控件以及系统控件的布局效果,可以彻底的屏蔽修改 density 所造成的所有未知和已知问题,但这样 AndroidAutoSize 也就无法对三方库进行适配

到这里autosize的框架接入就已经完成了,已经能够实现autosize的基本功能了

进阶使用

在 AndroidManifest.xml 中填写的设计尺寸,是整个项目的全局设计图尺寸但是如果某些 Activity 页面由于某些原因,这个页面的设计图尺寸和在 AndroidManifest.xml 中填写的设计图尺寸不一样该怎么办呢?则可以让这个页面的 Activity 实现 CustomAdapt ,CustomAdapt 接口的第一个方法可以修改当前页面的设计尺寸。

```

publicclassCustomAdaptActivityextendsAppCompatActivityimplementsCustomAdapt{/**

* 是否按照宽度进行等比例适配 (为了保证在高宽比不同的屏幕上也能正常适配, 所以只能在宽度和高度之中选择一个作为基准进行适配)

*

* @return {@code true} 为按照宽度进行适配, {@code false} 为按照高度进行适配

*/@OverridepublicbooleanisBaseOnWidth(){returnfalse;}/**

* 设计图尺寸为 1080px * 1920px, 高换算成 dp 为 960 (1920px / 2 = 960dp)

*

* 返回的设计尺寸, 单位 dp

* {@link #getSizeInDp} 须配合 {@link #isBaseOnWidth()} 使用, 规则如下:

* 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 则应该返回设计图的总宽度

* 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 则应该返回设计图的总高度

* 如果您不需要自定义设计图上的设计尺寸, 想继续使用在 AndroidManifest 中填写的设计图尺寸, {@link #getSizeInDp} 则返回 {@code 0}

*

* @return 单位 dp

*/@OverridepublicfloatgetSizeInDp(){return667;}}

```

如果你想放弃某个activity的适配你只需要实现 CancelAdapt 接口即可

```

public class CancelAdaptActivity extends AppCompatActivity implements CancelAdapt{

...

}

```

当你想要自定义fragment时你需要在app初始化时开启支持

在Applicationl类的oncreate方法中添加

```

AutoSizeConfig.getInstance().setCustomFragment(true);

```

万能解决方案

在任何情况下本来适配正常的布局突然出现适配失效,适配异常等问题,只要重写 Activity 的 getResources() 方法即可,如果是 Dialog、PopupWindow 等控件出现适配失效或适配异常,同样在每次 show() 之前调用 AutoSize#autoConvertDensity() 即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值