Android 平板UI适配方案|8月更文挑战

4,493 阅读3分钟

Android 平板UI适配方案

由于是安卓系统的碎片化严重,适配成为开发者越来越头疼的问题,该文章的适配是UI适配。 由于是新项目开发,最终使用的是今日头条适配方案,侵入低,效果好,可以很轻松的修改参数达到适配设计图的目的。

常用的适配方案

一、宽高限定符适配

含义

res文件夹中,创建很多values-的文件夹,计算出对应的dimen的值,类似下面目录


├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-800x480
│   ├── ├──values-860x540
│   ├── ├──values-1024x600
│   ├── ├──values-1024x768
│   ├── ├──...
│   ├── ├──values-2560x1440

缺点

这个方案有一个致命的缺陷,那就是需要精准命中才能适配,容错率差;并且我们在计算dimen也会有比较大的麻烦,虽然有自动生成的工具。

二、smallestWidth限定符适配

含义

与第一种方法类似,解决了第一种方法的容错差的问题,类似于mipmap中的资源,会自动找寻与自己相近的资源文件,在拉丁吴老师的文章中力挺这种方法。


├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-sw320dp
│   ├── ├──values-sw360dp
│   ├── ├──values-sw384dp
│   ├── ├──values-sw400dp
│   ├── ├──...
│   ├── ├──values-sw600dp

三、鸿神 的 AndroidAutoLayout

含义

让你的Activity继承自AutoLayoutActivity,在AndroidManifest中就指定设计图的尺寸,在写布局文件时,就可以直接写px,框架会通过px自动换算


<meta-data android:name="design_width" android:value="768">
</meta-data>
<meta-data android:name="design_height" android:value="1280">
</meta-data>

缺点

我们能够想到,因为框架要在运行时会在onMeasure里面做变换,我们自定义的控件可能会被影响或限制,可能有些特定的控件,需要单独适配,这里面可能存在的暗坑是不可预见的,还有一个比较重要的问题,那就是整个适配工作是有框架完成的,而不是系统完成的,一旦使用这个框架,未来一旦遇到很难解决的问题,替换起来是非常麻烦的,而且项目一旦停止维护,后续的升级就只能靠你自己了,这种代价团队能否承受?已经停止维护了

四、今日头条适配方案

含义

通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题。

问题

  • 在使用一些第三方View的时候,由于第三方View并不是按照我们的UI设计尺寸来的,所以会引起偏差。 我们其实可以减少使用第三方的View,或者使用一些分辨率比较齐全的第三方View。

  • 使用自定义dialog正常,但使用系统自带dialog时可能会出现显示不全的场景,这时需要修改dialog的大小。

    解决:blog.csdn.net/u011368551/…

实现方法

app/build.gradle


implementation 'me.jessyan:autosize:1.1.2'

manifest.xml application 标签内


<meta-data
            android:name="design_width_in_dp"
            android:value="853" />
        <meta-data
            android:name="design_height_in_dp"
            android:value="553" />

五、使用今日头条适配方案问题汇总,持续更新。

1. 问题一

  • 出现场景

横屏应用,在按home按键或者锁屏,当软件进入后台时,保持手机的竖屏,此时再产生新的Fragment更新UI时,有几率出现适配错误。

  • 原因分析

在锁屏或进入后台时,虽然应用固定为横屏,但手机在竖屏状态下,会让软件获取到竖屏状态,以至于新UI产生时,产生宽和高相反的适配效果。

  • 解决办法

Issue上的解决办法:github.com/JessYanCodi…

我的解决办法:

在Activity中

 @Override
    public Resources getResources() {
        //需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat
        int width = AutoSizeConfig.getInstance().getScreenWidth();
        int height = AutoSizeConfig.getInstance().getScreenHeight();
        AutoSizeCompat.autoConvertDensity(super.getResources(), 961, width > height);
        return super.getResources();
    }

2. 问题二

  • 出现场景

使用系统自带dialog时可能会出现显示不全的场景。

  • 原因分析

由于修改的是系统的density值,所以系统的view也会被适配。

  • 解决办法

更改原生的Dialog大小,在Dialog执行show方法之后再去设置,否则无效

if (mAlertDialog.getWindow() != null) {
            WindowManager.LayoutParams lp = mAlertDialog.getWindow().getAttributes();
            lp.width = 300;  // 宽度,可根据屏幕宽度进行计算
            lp.gravity = Gravity.CENTER;
            mAlertDialog.getWindow().setAttributes(lp);
        }