多形态设备
多形态设备 · androidx.wear.compose
TV Material:先设计焦点路径Wear 1.7.0-alpha07
使用 TV 专用 Card、Button、Carousel 与 NavigationDrawer 支持遥控器操作。
最后更新 2026-08-01
复制即用
@Composable
fun MovieRow(movies: List<Movie>, onOpen: (Movie) -> Unit) {
LazyRow {
items(movies) { movie ->
MovieCard(movie, onOpen = { onOpen(movie) })
}
}
}
@Composable
fun MovieCard(movie: Movie, onOpen: () -> Unit) {
Card(
onClick = onOpen,
modifier = Modifier
.width(240.dp)
.aspectRatio(CardDefaults.HorizontalImageAspectRatio),
scale = CardDefaults.scale(focusedScale = 1.05f),
) {
MoviePoster(movie)
}
}TV 的基本交互不是触摸,而是方向键移动焦点再确认。androidx.tv.material3.Card 和 Button 提供 focused 状态的缩放、边框、颜色等视觉反馈;这不是手机 Card 的装饰性替换,而是操作可见性的组成部分。
先画焦点路径
排列内容时先画出方向键的焦点路径:
- 从导航到内容:方向键下键能到达内容区。
- 横向列表之间:左右键在列表间切换。
- 弹层打开与关闭后:焦点回到哪里(
LaunchedEffect(Unit) { focusRequester.requestFocus() })。
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
Card(
onClick = {},
modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged { if (it.isFocused) highlight() },
) { ... }TV 专用组件
| 组件 | 用途 |
|---|---|
Card / Button | 带 focused 视觉反馈的交互元素 |
Carousel | 大图轮播(焦点居中) |
ImmersiveList | 沉浸式列表 |
NavigationDrawer | 大屏抽屉导航 |
常见陷阱
- 焦点丢失:弹层关闭后焦点不回到预期位置。
- 不可聚焦的目标:
onClick才有焦点,纯展示元素别加。 - 焦点顺序不可预测:动态列表 + 焦点要小心。
- 以为手机 Card 通用:TV Card 的 focused 反馈是操作可见性的一部分。
要点
- 方向键 + 确认是基本交互;focused 视觉反馈保证操作可见。
- 先设计焦点路径:导航→内容、列表间、弹层焦点回归。
- Carousel/ImmersiveList/NavigationDrawer 处理常见大屏结构。
- 每个可操作目标可聚焦、顺序可预测。