目前两类比较主流的android屏幕适配

  前言:本文只是笔者在学习了部分优秀文章后写的理解、归纳、总结,是哪些优秀文章呢?我们先热烈鼓掌,恭迎大佬:
Android 目前稳定高效的UI适配方案
一种极低成本的Android屏幕适配方式。如果我理解能帮到你,那就再好不过了。

  android的碎片化使得每一个开发者不得不面对屏幕适配这一个问题,个人认为,目前行业上比较流行的适配方案大体可以分为两类:

  一类是静态适配,包括宽高限定符适配方案、最小宽度限定符适配方案,这类方案主要是预先尽可能多的在res目录下定义不同分别率的dimens文件,APP运行时系统会自动根据目标设备的分辨率找到对应分别率下的dimens文件,根据此文件下对应的值渲染控件的大小,所以可以看做静态适配。Android 目前稳定高效的UI适配方案这篇文章对这类方案做了比较详细的讲解, 推荐看看。

  另一类就是动态适配了,代表方案就是今日头条团队开源的一种极低成本的Android屏幕适配方式

  为什么会存在这两类方案呢?在开始这个问题前,我们先看一个公式:

  • px = dp * (dpi / 160);

  我们可以简单的认为:

  • px是系统用的,系统以px为单位画出控件的大小;
  • dp是人用的,程序员以dp为单位在布局文件中设置控件的大小;
  • 当系统在渲染一个控件时,系统会将布局文件中的dp值通过dpi转化为px值,再来画控件,

  到这里,我们可能会疑问了:为什么px就是系统用的,dp是人用的。其实,在布局的时候,Android并不推荐我们使用px这个真实像素单位,因为不同的手机之间,分辨率是不同的,比如一个96*96像素的控件在分辨率越来越高的手机上会在整体UI中看起来越来越小。如图:
在这里插入图片描述
出现类似于上图这样这样,整体的布局效果可能会变形,所以px这个单位在布局文件中是不推荐的。再来看看下面这段布局文件中dp转化的源码:
在这里插入图片描述
  通过上面的源码可见,如果是px值的话,系统就直接用这个值了,而如果是dp值的话,系统会根据设备的density来对dp值进行相应的缩减,这里的density就是上述公式中的(dpi/160),所以上述公式也可形变如下:

  • px = dp * density

  由于不同分辨率下,dpi将会不同,比如:
在这里插入图片描述
  所以,布局时,Android推荐使用dp作为尺寸单位来适配UI,用dp会让系统走一个dp值转换为目标设备px值的过程,通过这个过程,在分辨率较低的手机中,可能1dp=1px,而在分辨率较高的手机中,可能1dp=2px,这样的话,一个96*96dp的控件,在不同的手机中就能表现出差不多的大小了。

  到此,我们上面讨论的都是不同手机导致不同分别率下的适配,通过用dp值布局可以解决90%的屏幕适配。下面我们来看看,相同分别率的设备,dpi值不同时的适配。

  综上,我们现在知道碎片化的最主要原因就是这个变量dpi的计算规则了,这个dpi值叫做像素密度,通常情况下,一部手机的分辨率是宽x高,屏幕大小是以寸为单位,理想情况下, dpi值可以通过如下公式计算获取:

在这里插入图片描述
  举个例子:屏幕分辨率为:1920*1080,屏幕尺寸为5吋的话,那么dpi为440。

在这里插入图片描述

  但现在问题是,不同的设备厂商,他不按这个规则来给出dpi,这就导致相同分辨率的设备,其dpi也可能不相同,比如Google 的Pixel2(19201080)的dpi是420而不是480,也就是说,在Pixel2中,1dp=2.625px,这样会导致相同分辨率的手机中,这样,一个100dp100dp的控件,在一般的1080P手机上,可能都是300px,而Pixel 2 中 ,就只有262.5px,这样控件的实际大小会有所不同

  为了更形象的展示,假设我们在布局文件中把一个ImageView的宽度设置为360dp,那么在下面两张图中表现是不一样的:

  图一是1080P,480dpi的手机,图二是1080P,420dpi的手机

在这里插入图片描述

在这里插入图片描述
  从上面的布局中可以看到,同样是1080P的手机,差异是比较明显的。在这种情况下,我们的UI可能需要做一些微调甚至单独适配。那么上述两类适配方案都是怎样来进行适配的呢?

  要理解Android的屏幕适配,除了要理解上述提到的那个公式,我们还要明确一个事情,那就是屏幕适配,无非就是要解决两个问题:1、不同手机,不同分别率的问题,2、相同分别率,dpi值不同的问题。 下面我们就围绕这两个问题来看看屏幕适配的发展历史。先来看看静态适配方案:

  宽高限定符适配

  简单说,就是穷举市面上所有的Android手机的宽高像素值,放到项目资源文件下。

  最小宽度限定符适配

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

  可见,静态适配方案都是预先准备一套dimens资源文件供系统自行选择,具体的原理拉丁吴老师已经做了很容易理解的解说,这里不再赘述了。恭迎大佬:
Android 目前稳定高效的UI适配方案
当你沉浸在大佬的思绪中时,记得要注意理解并找到宽高限定符适配方案和sw限定符适配方案的区别哦!

  动态适配:今日头条适配方案

  今日头条适配方案我之所以归为动态适配,是因为它主要是动态去修改系统界面的density值:density = 设备真实宽(单位px) / 360,接下来只需要把我们计算好的 density 在系统中修改下即可,代码实现如下:
在这里插入图片描述
同时在 Activity#onCreate 方法中调用下。代码比较简单,也没有涉及到系统非公开api的调用,因此理论上不会影响app稳定性。

  那么,静态适配方案和动态适配方案又有哪些区别呢?

  其实,无论哪种方案,px值都是通过如下公式计算的:

  • px = dp * density

  区别就是,静态适配方案的density是通过dpi/160计算获得,即:

  • px = dp * (dpi / 160)

它本质上还是用的设备的dpi,当前设备的dpi值在整个APP的生命周期中至始至终都是不变的,dpi的控制权是在设备厂商手里的,他说是多少就是多少,然而市面上那么多厂商,这就导致同一分别率下,dpi值不尽相同,density不尽相同,我们按一个分别率的设计稿来布局后,不同手机下同一界面就要么过大,要么显示不满的适配问题。所以需要变的只是我们预先要提供的dimens资源种类。

  再来看看今日头条适配方案,假设设计图宽度是360dp,以宽维度来适配。那方案的density = 设备真实宽(单位px) / 360。不同于上面的静态方案,今日头条适配方案完全抛弃了dpi值这个变量,不被厂商牵着鼻子走,大有任你厂商风里来雨里去,我自岿然不动的意境(我就静静的看着你装13)。

  我们可以这样认为,dpi值是主观给予的(厂商定的),设备真实宽度(单位px)是客观存在的(物理宽度),正是基于这两个现实,才有了这两类适配方案的情况。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值