Android技能树 — 屏幕适配小结,2024最新腾讯Android面试分享

本文介绍了Android中的dp和density概念,探讨了如何处理不同屏幕尺寸和分辨率的适配问题,比较了生成values文件夹、values-sw文件夹和百分比布局库的适配方法,以及它们各自的优缺点。
摘要由CSDN通过智能技术生成
  • hdpi(高)~240dpi
  • xhdpi(超高)~320dpi
  • xxhdpi(超超高)~480dpi
  • xxxhdpi(超超超高)~640dpi

1.4 dp 和 density

其实dp 本来是叫dip (Density Independent Pixels),所有有时候面试的别人,面试者会弄错,把dip当做了dpi,所以你问他请说下 dp 和 dip ,他会把 dip说成dpi的内容。

我们举例说下这块知识点: 要画一个 高和宽各为屏幕的一般的按钮,我们假设有二块屏幕,一块是100 X 100 ,一块是 200 X 200 ,那这时候第一块的屏幕上我们写Button 应该为:

第二个屏幕的Button应该为:

这样是不是都各自占了屏幕的高宽的一半,但是假如有第三个屏幕 300 X 300 呢,难不成再写一个Button的高宽值? 所以我们可以用一种单位来代替,但是这种单位可以在不同的屏幕环境下,值是不同的。比如我们就把这个单位当做“haha”。

比如我们现在都这么写:

这时候在100 x 100的时候, 50haha = 50px ,在200 X 200 屏幕的时候 , 50 haha = 100px , 在 300 X 300 屏幕的时候,50haha 等150px。

这个感觉就很像你跟别人说我欠你50 money,如果在中国,代表你欠别人50元人民币,但是如果在美国,你这么说,指你欠50美元,也就是欠了三百多元人民币。(这个例子不要跟我较真,我就意思意思而已)

所以dp就是类似我们上面自己定义的haha这个单位。

比如50dp = 50px ,这时候1dp = 1px , 50dp = 100px的时候 是 1dp = 2px ,所以我们可以看到倍数分别为 1 和 2 ,我们用density来代表这个倍数。也就是说: dp * density = px,这时候就是 50 dp * 1 = 50px , 50dp * 2 = 100px

(就像是我说我欠你50 money,在中国,这个density就是1 , 也就是欠你50元人民币,在美国可能就是指300多人民币,这个density也就是 美元换算成人民币的倍数)

那么这个density具体是怎么来的呢?其实很简单,记不记得我们前面说过dpi ,也就是屏幕的密度,我们就用这个密度来做比较,比如我们 把160dpi 作为标准,那另外一个手机是320dpi ,那么这个density就是 (320/160 = 2)。 所以我们再次把公式 : dp * density = px 转变为: dp * (dpi / 160) = px

那么为什么用160dpi作为标准呢,以前看到文章提过:mdpi基于第一款 Android 设备 ″T-Mobile G1″ 的屏幕配置(缩放系数scale=1)。

1.5 基础知识小结

所以假如我们现在的手机分辨率知道了,手机屏幕尺寸也知道了。我们通过公式求出 dpi ,然后 dpi / 160 就是当前手机的density,然后我们就知道我写了1dp 在这台手机上具体是多少px了。

具体的安卓手机尺寸四个分类及6中dpi分类:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的某台手机的dpi,density,分辨率等如何获取呢,:

DisplayMetrics mDisplayMetrics = getResources().getDisplayMetrics();
//横向分辨率
int width = mDisplayMetrics.widthPixels;
//竖向分辨率
int height = mDisplayMetrics.heightPixels;
//density值
float density = mDisplayMetrics.density;
//dpi的值就等于density * 160
float dpi = density * 160;

也许有人说,那我们使用dp不是已经完美的实现了各种兼容性吗,就像我们上面提到过的,100 X 100 ,200X200 , 300 X 300的屏幕,我们都只要写50haha, 就分别代表了50,100,150,不是就占了各自屏幕的一半了么。理论上的确是这样,但是我们刚提过我们的density是等于 (dpi / 160),而dpi又由分辨率和屏幕尺寸同时决定,安卓手机的碎片化太过严重,所以很多手机虽然分辨率不同及屏幕尺寸不同,造成最后的dpi一样,所以最后的density也一样,就造成了适配实现不全。假设我们多了一个400X400 的设备,因为它的屏幕尺寸也同时变大了很多,所以最终的density和300X300一样,那这时候我们写了50haha,也就代表了150px,这时候明显在400X400上面并没有显示为一半,甚至当这个400X400的设置的屏幕尺寸超级大,反而可能算下来的density与100X100的一样,那这时候50haha可能就只有50px,则显示差距就更大了。 (其实主要原因就是dpi不是单独由分辨率来决定,同时还有屏幕尺寸影响,所以二个变量同时作用,造成不同分辨率的手机最后的density也可能相同。这样dp转换成的px也就相同了,但是手机的分辨率本身有不同,这时候就会出现适配不对。)

2 各类适配方案

2.1 生成分辨率values文件夹

因为我们上面提过 , px = (dpi / 160) * dp, 但是dpi又是同时由分辨率和屏幕尺寸同时决定,造成了不同的分辨率,dpi可能一样,这样最终得到的px一样,比如都是占屏幕的一半,300X300得到的可能是150,但是400X 400得到的也是150,这时候就不对了。

那我们就想到了。我们能不能不是同时受到分辨率和屏幕尺寸决定,而是只受一个因素来影响,这样就是真正的按比例来了。比如300X300是150,400X400是200,500X500是250,是只受分辨率的影响,所以分辨率大的,最终得到的结果一定就大。所以我们就不能使用dp了。而是一个新的单位,而这个单位是根据不同的分辨率,得到不同的值,那怎么计算呢,就是穷举法,比如刚才的300X300,我们规定1 haha等于1 px,然后再600 X 600里面,1 haha 等2 px , 1200X1200里面是 1 haha 等于 3 px 。所以我们在不同分辨率下的values文件夹下写上不同的值:

300X300下
1px
600X600下
2px
1200X1200下
3px

所以这个就是方案1 ,附上文章链接。

Android 屏幕适配方案 我们可以看下面的图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到列举了所有可能的屏幕分辨率的values,然后手动按照倍数,进行相应的赋值。当然这些文件不可能手写,通过Java自动生成相应的文件:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这样最终影响结果的就只是分辨率的了,分辨率越大的,x1的值越大。

但是这个方案有一个致命的缺陷,那就是需要精准命中才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。


2.2 生成values -sw 文件夹

可以参考:

Android 目前最稳定和高效的UI适配方案

骚年你的屏幕适配方式该升级了!-smallestWidth 限定符适配方案

其实这个方式跟上面的2.1方法原理可以说一模一样。唯一的区别就是使用了sw来保证一定的容错性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们看到其实就是把上面具体的分辨率values改成了values - sw而已。


2.3 百分比布局库

Android 百分比布局库(percent-support-lib) 解析与扩展 Android 增强版百分比布局库 为了适配而扩展

其实这个也是很简单的,字面意思,我写了这个Button宽度为父布局的百分之50,则在不同手机上,都是占据了百分之50。使用过过百分比布局的人都应该知道,我们写的时候是这么写的:

<android.support.percent. PercentRelativeLayout
xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>

其实原理很简单,就是动态计算实际的百分之50在不同机器的时候到底占了多少px,2.1,2.2则是等于提前帮我们计算好了具体的px,然后写在了文件里面,然后我们去读数据。

那它的实现原理是什么呢?简单来说就是二步:

  1. 获取用户到底填了多少的百分比数值
  2. 获取父布局的空间,然后乘以用户填的百分比数值,或者一个新数值,然后赋值给该控件。

我们一步步来看源码:

2.3.1 获取用户到底填了多少的百分比数值:

我们知道我们的百分比布局中的核心属性是子控件填写:

app:layout_heightPercent=“20%”
app:layout_widthPercent=“30%”

所以我们需要在PercentRelativeLayout中遍历它下面的子控件,然后分别获取每个子控件的百分比数值。 其实很简单,写过自定义View的人应该都知道,因为这个其实就是自定义属性而已。

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PercentLayout_Layout);
float value = array.getFraction(R.styleable.PercentLayout_Layout_layout_widthPercent, 1, 1,-1f);

2.3.2 获取计算后的值并且赋值:

因为要动态获取父控件的控件,同时把新的值赋值给子控件,所以该行为在onMeasure方法中执行。

//传入的ViewGroup.LayoutParams params是遍历的每个子View的LayoutParams
public void fillLayoutParams(ViewGroup.LayoutParams params, int widthHint,
int heightHint) {
// Preserve the original layout params, so we can restore them after the measure step.
mPreservedParams.width = params.width;
mPreservedParams.height = params.height;

if (widthPercent >= 0) {
params.width = (int) (widthHint * widthPercent);
}
if (heightPercent >= 0) {
params.height = (int) (heightHint * heightPercent);
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, “after fillLayoutParams: (” + params.width + ", " + params.height + “)”);
}
}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

学习福利

【Android 详细知识点思维脑图(技能树)】

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

详细整理在GitHub点击可见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

[外链图片转存中…(img-k3XCa0Uk-1711356584417)]

详细整理在GitHub点击可见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值