以下是基于上面两篇文章分析的笔记
UI适配:
px是安卓中的真实像素,但并不使用这种做法,因为每个手机的像素密度不同,造成相同的px在不同的手机占的百分比不相同。
解决:
1.用dp直接适配
公式:dp=px(dpi/160)
其中dpi是软件上人定的像素密度,而ppi是物理上真正的像素密度。dpi是参考ppi的像素密度,在一定的区间内人为取值一个特定值。如1080720的dip为320,19201080的dpi为480,所以1dp在两个不同的手机上分别为2px和3px。
缺点:dp只能解决90%的适配问题,因为并不是所有的1080P的手机dpi都是480,比如Google 的Pixel2(19201080)的dpi是420,也就是说,在Pixel2中,1dp=2.625px,这样会导致相同分辨率的手机中,这样,一个100dp100dp的控件,在一般的1080P手机上,可能都是300px,而Pixel 2 中 ,就只有262.5px,这样控件的实际大小会有所不同。
2.宽高限定符适配
就是穷举市面上的所有android的宽高像素值。
计算方法为:把宽设置为320份,高设置为480份。分别算出每一份在不同手机所占的px值。
不过我们并不能把所有手机的限定符都写出来,这时就可以用到一个谷歌提供的像素比文件自动适配。可以为每个设定特定的值
3.UI适配框架(已经停止维护)
鸿洋的适配方案的项目也来自于宽高限定符方案的启发。
使用方法也很简单:
第一步:
在你的项目的AndroidManifest中注明你的设计稿的尺寸。
第二步:
让你的Activity继承自AutoLayoutActivity.
然后我们就可以直接在布局文件里面使用具体的像素值了,比如,设计稿上是96*96,那么我们可以直接写96px,APP运行时,框架会帮助我们根据不同手机的具体尺寸按比例伸缩。
这可以说是一个极好的方案,因为它在宽高限定符适配的基础上更进一步,并且解决了容错机制的问题,可以说完美的达成了开发高效和适配精准的两个要求。
但是我们能够想到,因为框架要在运行时会在onMeasure里面做变换,我们自定义的控件可能会被影响或限制,可能有些特定的控件,需要单独适配,这里面可能存在的暗坑是不可预见的,还有一个比较重要的问题,那就是整个适配工作是有框架完成的,而不是系统完成的,一旦使用这个框架,未来一旦遇到很难解决的问题,替换起来是非常麻烦的,而且项目一旦停止维护,后续的升级就只能靠你自己了,这种代价团队能否承受?已经停止维护了。
不过仅仅就技术方案而言,不可否认,这是一个很好的开源项目。
4.今日头条适配方案(更新)
https://mp.weixin.qq.com/s?__biz=MzI1MzYz
可以说,这也是相对比较完美的方案,我先简单说一下这个方案的思路,它是通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题。
比如,设计稿宽度是360px,那么开发这边就会把目标dp值设为360dp,在不同的设备中,动态修改density值,从而保证(手机像素宽度)px/density这个值始终是360dp,这样的话,就能保证UI在不同的设备上表现一致了。
这个方案侵入性很低,而且也没有涉及私有API,应该也是极不错的方案,我暂时也想不到强行修改density是否会有其他影响,既然有今日头条的大厂在用,稳定性应当是有保证的。
但是根据我的观察,这套方案对老项目是不太友好的,因为修改了系统的density值之后,整个布局的实际尺寸都会发生改变,如果想要在老项目文件中使用,恐怕整个布局文件中的尺寸都可能要重新按照设计稿修改一遍才行。因此,如果你是在维护或者改造老项目,使用这套方案就要三思了。
小结
讨论的上述几种适配方案都是可以实际用于开发中的比较成熟的方案,而且确实有很多开发者正在使用。不过由于他们各自都存在一些缺陷,所以我们使用了上述方案后还需要花费额外的精力着手解决这些可能存在的缺陷。
5.smallestWidth适配
就是根据手机算出来的dp的值,然后去寻找values-swxxxdp中的相等或相近的值,这样可以提高容错机制
资源地址:
https://github.com/ladingwu/dimens_sw
刘海屏、水滴屏适配
对于刘海屏的状态栏有两种显示:
只有在Android 4.4(API Level 19)以上才支持设置透明状态栏:
一种是背景半透明的、字体可见的、可被布局背景延申的沉浸式:
沉浸式踩坑指南
方法一:为Activity设置style,添加一个属性:
<item name="android:windowTranslucentStatus">true</item>
方法二:在Activity的onCreate()中为Window添加Flag
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
一种是背景全透明、字体不可见、可被布局背景延申的全屏式:
方法一:为Activity设置style,添加属性:
<item name="android:windowFullscreen">true</item>
方法二:在Activity的OnCreate()中添加代码:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN |View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
手机屏幕高宽比例越来越大,我们还需要额外做一下适配才能使应用在所有手机上都能全屏显示,具体方式有两种:
ratio_float = 屏幕高 / 屏幕宽,建议设置 ratio_float为2.2或者更大
方式一:在AndroidManifest.xml中配置支持最大高宽比
<meta-data android:name="android.max_aspect"
android:value="ratio_float" />
方式二:(API LEVEL 26)
android:maxAspectRatio="ratio_float"
1.沉浸式状态栏的适配
方法一:给最外层的view的设置fitsSystemWindows="true"
方法二:在布局中添加一个和状态栏高度相同的View ,是让屏幕预留出状态栏的高度,这里在根布局中添加了一个透明的View,高度和状态栏高度相同。这种方法的好处是可以自定义填充状态栏View的背景,更灵活地实现我们想要的效果。
方法三.根据状态栏高度手动设置paddingTop。
全屏的适配方案看这篇文章https://juejin.im/post/5c99dae85188252d93208b15
各种标签:https://blog.csdn.net/weixin_41673515/article/details/95660275