Compose 适配 - 通过 UiMediaScope 获取设备信息

官方页面

一、概念

设备信息是动态更新的,需要对其进行监控,并在发生任何更新时触发重组。mediaQuery() 和 derivedMediaQuery() 函数抽象了信息检索的细节,让你可以专注于定义触发布局更新的条件。UiMediaScope 代表了当前的设备能力和上下文环境,当发生变化时此对象会动态更新,查询函数会使用更新后的 UiMediaScope 对象对 Lambda 进行求值。

|---------------------|---------------------------------------------------------------------------------------------------------------|
| mediaQuery() | @Composable fun mediaQuery( query: UiMediaScope.() -> Boolean ): Boolean = LocalUiMediaScope.current.query() |
| derivedMediaQuery() | @Composable fun derivedMediaQuery( query: UiMediaScope.() -> Boolean ): State<Boolean> |

|----------------------------------|---------------------------------------------------|---------------------------------------|
| UiMediaScope 参数 | 类型及说明 ||
| windowWidth windowHeight 当前窗口的宽高 | Dp ||
| windowPosture 当前设备姿态 | UiMediaScope.Posture | .Flat |
| windowPosture 当前设备姿态 | UiMediaScope.Posture | .Tabletop |
| windowPosture 当前设备姿态 | UiMediaScope.Posture | .Book |
| pointerPrecision 当前指针输入的最高精度 | UiMediaScope.PointerPrecision 同时存在多个输入设备会返回精度最高的。 | .Fine 精细:鼠标、触控板、手写笔。 |
| pointerPrecision 当前指针输入的最高精度 | UiMediaScope.PointerPrecision 同时存在多个输入设备会返回精度最高的。 | .Coarse 粗略:触摸屏(手指)。 |
| pointerPrecision 当前指针输入的最高精度 | UiMediaScope.PointerPrecision 同时存在多个输入设备会返回精度最高的。 | .Blunt 迟钝:摇杆。 |
| pointerPrecision 当前指针输入的最高精度 | UiMediaScope.PointerPrecision 同时存在多个输入设备会返回精度最高的。 | .None 无:没有输入方式。 |
| keyboardKind 可用的键盘类型 | UiMediaScope.KeyboardKind | .Physical 物理硬件。 |
| keyboardKind 可用的键盘类型 | UiMediaScope.KeyboardKind | .Virtual 虚拟键盘。 |
| keyboardKind 可用的键盘类型 | UiMediaScope.KeyboardKind | .None 无:未连接硬件也没有显示虚拟键盘。 |
| hasCamera 是否支持摄像头 | Boolean ||
| hasMicrophone 是否支持麦克风 | Boolean ||
| viewingDistance 用户与屏幕之间的典型距离 | UiMediaScope.ViewingDistance | .Near 近距离:大多数个人设备的默认设置,手机、平板、笔记本、显示器。 |
| viewingDistance 用户与屏幕之间的典型距离 | UiMediaScope.ViewingDistance | .Medium 稍远:车载设备、底座模式的平板。 |
| viewingDistance 用户与屏幕之间的典型距离 | UiMediaScope.ViewingDistance | .Far 相当远:电视。 |

二、使用

2.1 窗口大小

Kotlin 复制代码
when {
    mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout()
    mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout()
    mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout()
}

2.2 设备形态

Kotlin 复制代码
val isExpanded by derivedMediaQuery {
    windowWidth >= WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND.dp
}
val isMedium by derivedMediaQuery {
    windowWidth >= WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND.dp
}
when {
    isExpanded -> ThreePaneLayout()
    isMedium -> TwoPaneLayout()
    else -> SinglePaneLayout()
}

2.3 输入精度

Kotlin 复制代码
val buttonSize = if (mediaQuery { pointerPrecision == UiMediaScope.PointerPrecision.Fine }) {
    10.dp
} else {
    20.dp
}

2.4 检测键盘

Kotlin 复制代码
if (mediaQuery { keyboardKind == UiMediaScope.KeyboardKind.None }) {
    // 提示连接键盘
}

2.5 检测麦克风/摄像头

Kotlin 复制代码
if (mediaQuery { hasMicrophone }) {
    MicButton()
}

if (mediaQuery { hasCamera }) {
    CameraButton()
}

2.5 检测距离

Kotlin 复制代码
val fontSize = when {
    mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Far } -> 20.sp
    mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Medium } -> 18.sp
    else -> 16.sp
}

三、预览

Kotlin 复制代码
@Composable
fun TablettopPreview() {
    // 1.启用 mediaQuery 函数。
    ComposeUiFlags.isMediaQueryIntegrationEnabled = true
    val currentUiMediaScope = LocalUiMediaScope.current
    // 2.定义一个实现 UiMediaScope 接口的自定义对象。
    // 该对象覆盖了 windowPosture 参数,其余参数的解析将委托给 currentUiMediaScope 对象。
    val uiMediaScope = remember(currentUiMediaScope) {
        object : UiMediaScope by currentUiMediaScope {
            override val windowPosture: UiMediaScope.Posture = UiMediaScope.Posture.Tabletop
        }
    }
    // 3. 将该对象设置为 LocalUiMediaScope。
    CompositionLocalProvider(LocalUiMediaScope provides uiMediaScope) {
        // 4.调用组件进行预览
        when {
            mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout()
            mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout()
            mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout()
        }
    }
}
相关推荐
阿巴斯甜1 小时前
必看12
android
阿巴斯甜1 小时前
必看11
android
solo_991 小时前
Perftto 使用命令添加标签
android
阿巴斯甜2 小时前
必看10
android
阿巴斯甜2 小时前
必看9
android
阿巴斯甜2 小时前
必看6
android
angerdream2 小时前
Android手把手编写儿童手机远程监控App之SQLite详解
android
阿巴斯甜2 小时前
必看5
android
雪铃儿3 小时前
Shorebird 之外,Flutter Android 热更新还有什么选择
android·前端