Jetpack Compose简单的屏幕适配方案

本篇过于简陋,请移步第二版: Jetpack Compose屏幕适配(第二版)

学习Compose

最近鼓起勇气开始学习Compose,听说Compose可以提升开发效率、降低bug出现的概率,摆脱各种xml的束缚,所以打算丢弃所有和View相关的东西重构项目。
1.0版本发布的时候,那种风格和思维方式着实让我吓了一跳,以至于出来这么就都没有去学习。最近官方订阅号一直在强推Compose,再对比了一下如今的开发效率,作为跨界三流程序员,我是真的不想再深入研究View之类的东西了。这次花了一点时间学习了一下,探索出了一个比较简单的方式实现屏幕适配。用我的能力去理解,大概就是:在不同设备中,界面布局尽量与设计图保持一致。

开始

首先,阅读这篇文章,了解一下适配的思路 :一种极低成本的Android屏幕适配方式

当了解了各项重要的指标之后,整理下来无非就是三样东西:DP(密度无关像素)PX(像素)Density(像素密度)
在Compose中,从官方的介绍里面不难看出,定义尺寸需要用到以下两种方式:

  • 组合函数(暂且叫控件吧)的尺寸
    Box(
        modifier = Modifier.size(100.dp, 100.dp)
    ) {
        //Content
    }

使用dp扩展方法,将数字(Number类)转化为DP对象

  • 文字尺寸
    Text(
        text = "Hello!!!",
        fontSize = 12.sp
    )

使用sp扩展方法,将数字(Number类)转化为TextUnit对象
对于尺寸的定义,目前我知道的就这两种,如果以后探索的更多,我会一直学习并记录。

核心

如果要适配设计图,其实就和之前的文章提到的一样,需要修改Density,但对于一个生手来说,修改底层的一些东西会不会碰到各种各样不好解决的问题?索性干脆不要改系统的density,直接把适配之后的尺寸换算出来,用作各个部件的宽高,应该能解决问题。

流程其实很简单:

  1. 获取设计图的Density
  2. 根据设计图的Density将尺寸换算为PX
  3. 将设计图的PX换算成当前屏幕的DP

代码

适用于控件

const val designWidth = 360f //设计图屏幕的宽度,视为一倍的尺寸
const val designHeight= 640f //设计图屏幕的高度,视为一倍的尺寸

val Number.compatDP: Dp
    get() {
        val res = Resources.getSystem()
        val displayMetrics = res.displayMetrics
        val density = if (res.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
             displayMetrics.widthPixels.toFloat() / designHeight
        } else {
             displayMetrics.widthPixels.toFloat() / designWidth
        }
        val pixel = toFloat() * density
        return (pixel / displayMetrics.density).dp
    }

适用于文字

const val designWidth = 360f //设计图屏幕的宽度,视为一倍的尺寸
const val designHeight= 640f //设计图屏幕的高度,视为一倍的尺寸

val Number.compatSP: TextUnit
    get() {
        val res = Resources.getSystem()
        val displayMetrics = res.displayMetrics
        val density = if (res.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
             displayMetrics.widthPixels.toFloat() / designHeight
        } else {
             displayMetrics.widthPixels.toFloat() / designWidth
        }
        val pixel = toFloat() * density
        return (pixel / displayMetrics.scaledDensity).sp
    }

注意中间计算density时,需要判断横竖屏,否则尺寸会有问题。
最后,只需要调用扩展方法compatDPcompatSP即可

特别注意!!!!

如果有使用纯 View 的界面跳转至 Compose 界面,尺寸会出现异常,因为 View 界面使用了修改 DisplayMetrics 的方式进行适配,这种方式是全局的,必须要在 Compose 界面中进行还原,基于项目紧急程度,暂时就不展开了。

结尾

这只是个人觉得最简单的一种方法,不需要导包写配置,如果有更好的办法请在评论区指导。
非科班出身,如有错误,欢迎指正。

你可能感兴趣的:(Jetpack Compose简单的屏幕适配方案)