Jetpack Compose Glimmer 中的 Surface

适用的 XR 设备
本指南可帮助您为以下类型的 XR 设备打造优质体验。
展示眼镜

在 Jetpack Compose Glimmer 中,surface 组件是一个基本构建块,表示按钮和卡片等组件的独特视觉区域或物理边界。

界面负责以下视觉和物理属性:

  • 裁剪:将其子项裁剪为指定形状。
  • 边框:绘制内边框以突出显示组件边界。获得焦点时,它会绘制一个带有焦点突出显示的更宽边框。
  • 背景:为表面区域应用背景颜色。
  • 深度效果:根据组件的状态(例如默认状态与聚焦状态)渲染 DepthEffect 阴影。
  • 内容颜色:提供表面内部的文字和图标颜色,默认情况下根据背景颜色计算得出。
  • 互动状态:在表面被按压时绘制按压叠加层,在获得焦点时绘制带有突出显示的更宽边框。

示例:创建界面

以下代码创建了一个具有剪裁、背景和默认边框的 Surface:

@Composable
fun SurfaceSample() {
    Box(Modifier.surface().padding(horizontal = 24.dp, vertical = 20.dp)) {
        Text("This is a surface")
    }
}

Interaction and Focus

Surfaces aren't focusable by default, so users can't interact with them. In most cases, surfaces should be interactive to let users consistently move focus and navigate between components. You can use the Compose focusable modifer for surfaces that are only intended to be focusable, or the Compose clickable modifer and other modifiers for surfaces that require actions.

You can create a focusable surface by combining a surface modifier with the focusable modifier:

@Composable
fun FocusableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        Modifier.surface(
                // Provide the same interaction source here and to focusable to make sure that
                // surface appears focused when interacted with.
                interactionSource = interactionSource
            )
            .focusable(interactionSource = interactionSource)
            .padding(horizontal = 24.dp, vertical = 20.dp)
    ) {
        Text("This is a focusable surface")
    }
}

Key points about the code

  • Shared interaction source: Both .surface() and .focusable() must share the same interactionSource. This lets the surface react to focus changes.

Similarly, you can create a clickable surface:

@Composable
fun ClickableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        Modifier.surface(
                // Provide the same interaction source here and to clickable to make sure that
                // surface appears focused and pressed when interacted with
                interactionSource = interactionSource
            )
            .clickable(interactionSource = interactionSource, onClick = {})
            .padding(horizontal = 24.dp, vertical = 20.dp)
    ) {
        Text("This is a clickable surface")
    }
}

代码要点

  • 共享互动来源:两者均有。surface() 和 。clickable() 必须共用同一 interactionSource。这样可确保视觉状态(例如按压或聚焦)保持同步,从而使界面能够以视觉方式对用户输入做出反应。

  • 修饰符顺序:修饰符的顺序至关重要。因为 。surface() 会剪裁布局,并将其放置在 之前clickable() 可确保触摸目标受限于表面的形状。如果 .clickable() 在先,互动区域可能会超出组件的可视剪裁边界。

SurfaceDepthEffect

SurfaceDepthEffect 类用于管理互动状态之间的阴影过渡:

  • depthEffect:界面处于默认状态时使用的阴影效果。
  • focusedDepthEffect:当表面处于聚焦状态时使用的阴影效果。