探究使用Compose如何去适配多UI的情况

111 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

image.png

好多天都没有更新文章了,之前连着更新了好多文章,这又是连着很多天没有更新,最近有点忙,再加上疫情,把人弄的也是心里慌慌的,但是最后想想,慌有什么用呢?不去看群里那些关于疫情的消息,关注自己的当下,干一些有意义的事情,比起来每天都在想自己阳了没阳更有意义。

为什么我会提出这样的一个问题呢?也是在实际开发项目中遇到的,估计大家也都会遇到,就是同一个功能模块,UI界面长的不一样,有的可能是来自于客户的要求,也得可能是因为设备差异比较大。就用登录界面来说:

image.png 其实功能都是一样的,可能就是UI上长的稍微有点差别,ViewModel里面的功能都是一样的,或者说功能的差别很小,遇到这种情况该怎么办?这里做几种方案的探讨。

  • 独立项目

    重新拉出一个git的分支另立一个项目去做独立的开发?感觉不太值得,毕竟后面维护起来比较麻烦,因为这个差别只是UI上面的,功能上基本都差不多,后面让不同的人维护,可能就出现同样的功能不同的代码的情况。本来需要一个人就可以做的事情,结果后面非得两个人才能做。所以我认为这样的方式不可取。

  • Flavor管理

    相信很多人都接触过Flavor管理的项目,Flavor可以将项目的差异隔离出来,对于不同的项目可以做差异化管理,这其实也是一个方法,但是也有相应的问题:

    • 问题1:如果是lib库那么就会出现多个lib的问题,如果lib库是给别人提供的,那么集成起来必须先了解每个库是干嘛用的。
    • 问题2:Flavoer管理的时候有一个基础的base库,有的时候难免会在base库里面关联一些只有在flavor里面才有的类或者资源,有的时候就会导致其他的flavor编译不过的问题。
  • Compose写多个Screen

    大家都知道Compose其实写界面挺简单的,像上面的UI也就是UI布局不一样,那么就针对不同的UI写多个screen就可以了。这样的写法相对于独立的项目来说会好一点,但是UI你还是要维护多套。所以我针对这种情况稍稍做了一下改进,最主要的还是使用compositionLocalOf 这个东西,之前我讲过相关的内容,也都是很基础的,大家可以去看看。其实就是一个全局的变量,这个东西和mutableStateOf结合使用,我觉得在compose里面实现这种多UI的适配还挺合适的。例如一个界面可能就是字体大小改了一下,padding改了一下,宽高改了一下,布局从横的调成竖的,像这种微小的改动,我觉得就可以通过这个来控制。具体的做法如下:

    • 定义一个数据类
    data class PaddingDimens(
       val top: Dp = 0.dp,
       val bottom: Dp = 0.dp,
       val start: Dp = 0.dp,
       val end: Dp = 0.dp
    )
    
    • 根据不同的UI建立不同的实例
    val screen1 = PaddingDimens(3.Dp,4.Dp,5.Dp,6.Dp)
    val screen1 = PaddingDimens(5.Dp,4.Dp,3.Dp,6.Dp)
    val padding = compositionLocalOf { mutableStateOf(PaddingDimens()) }
    
    • 使用
    CompositionLocalProvider(padding provides screen1){
        Box(
            modifier = Modifier.padding(top=padding.top)
        )
    }
    

    这样使用就可以达到UI适配的效果,并且这里面也不需要过多的使用if...else语句来控制。当padding发生改变的时候compose也会发生重组。

    当然这个只是针对一些微小的改动,如果UI几乎都不一样了,那么重新写一个screen是一种比较好的选择。

以上就是我针对多UI的一些想法,如果你有更好的方法,可以留言个我哦^_^