카드와 상호작용

카드는 정보를 표시하는 것 외에도 상호작용할 수 있습니다. textButton()와 같은 요소가 탭에 응답하도록 하려면 clickable()를 사용하여 클릭 핸들러를 생성하고 레이아웃 요소와 연결합니다.

다음 두 가지 기본 방법으로 Clickable를 구성하여 작업을 트리거할 수 있습니다.

  1. 활동 직접 실행: 활동을 즉시 열어야 하는 경우에 launchAction()를 사용합니다.
  2. 카드 서비스에 위임: loadAction()를 사용하여 TileService 내에서 로직을 트리거합니다. 이 접근 방식은 카드의 콘텐츠를 새로고침하거나, 상태를 업데이트하거나, 더 복잡한 활동을 실행할 수 있는 보다 유연한 접근 방식입니다.

내보낸 활동 실행

사용자가 탭하면 즉시 활동이 실행되어야 하는 경우 launchAction()를 사용합니다. 활동을 식별할 ComponentName를 제공합니다. 활동을 내보내야 합니다. 이 접근 방식을 사용하면 작업과 함께 Intent 추가 항목을 전달할 수 있습니다. 하지만 맞춤 Intent 플래그는 설정할 수 없습니다.

다음 예는 두 개의 추가 항목인 nameage를 사용하여 TileActivity를 실행하는 Clickable를 만드는 방법을 보여줍니다.

textButton(
    labelContent = {
        text("launchAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        launchAction(
            ComponentName(
                "com.example.wear",
                "com.example.wear.snippets.m3.tile.TileActivity",
            ),
            mapOf(
                "name" to ActionBuilders.stringExtra("Bartholomew"),
                "age" to ActionBuilders.intExtra(21),
            ),
        )
    ),
)

실행된 활동 내에서 인텐트 추가 항목에서 값을 가져옵니다.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // When this activity is launched from the tile InteractionLaunchAction,
    // "name" will be "Bartholomew" and "age" will be 21
    val name = intent.getStringExtra("name")
    val age = intent.getStringExtra("age")

    // ...
}

카드 서비스에서 상호작용 처리

보다 유연한 상호작용을 위해 loadAction()를 사용하세요. 사용자가 loadAction로 구성된 요소를 탭하면 시스템은 TileService.onTileRequest()를 다시 호출합니다. 이렇게 하면 서비스에서 로직을 실행하여 타일을 업데이트하고, 상태를 변경하고, 더 복잡한 작업을 실행할 수 있습니다.

카드 콘텐츠 새로고침

loadAction의 가장 간단한 용도는 새로고침을 알리는 것입니다. 인수 없이 loadAction를 호출합니다. 탭하면 시스템에서 onTileRequest()를 호출하여 서비스가 업데이트된 콘텐츠가 포함된 새 레이아웃을 반환할 수 있습니다.

textButton(
    onClick = clickable(loadAction()),
    labelContent = { text("Refresh".layoutString) },
)

여러 상호작용 요소 구분

카드에 여러 개의 상호작용 요소가 포함된 경우 ID를 Clickable 수정자와 연결할 수 있습니다.

onTileRequest() 내에서 requestParams.currentState.lastClickableId를 사용하여 이 ID를 확인하여 실행할 작업을 결정할 수 있습니다.

예: 딥 링크로 활동 실행

이 패턴은 딥 링크로 활동을 실행하는 데 적합합니다. 사용자가 카드를 탭하면 카드가 새로고침되고 서비스에서 ID를 검사한 후 새 활동을 실행합니다. 백 스택을 제어하려면 TaskStackBuilder를 사용하여 사용자에게 더 나은 탐색 환경을 제공하세요. 사용자가 요소를 탭하면 딥 링크된 화면 (예시의 message_detail/1 화면)으로 바로 이동합니다. .addNextIntentWithParentStack()가 사용되었으므로 상위 활동도 백 스택에 추가됩니다. 즉, 사용자가 뒤로 스와이프하면 바로 카드로 종료되는 대신 앱의 기본 화면 (예: MessageList)으로 이동합니다. 다시 스와이프하면 타일로 돌아갑니다.

그런 다음 TileActivity에서 googleandroidsnippets://app/message_detail/{id} 패턴과 일치하도록 탐색을 구성합니다.

TaskStackBuilder를 사용하여 사용자에게 더 나은 탐색 환경을 제공하세요. 사용자가 요소를 탭하면 딥 링크된 화면(이 예에서는 message_detail/1 화면)으로 바로 이동합니다. .addNextIntentWithParentStack()가 사용되었으므로 상위 활동도 백 스택에 추가됩니다. 즉, 사용자가 뒤로 스와이프하면 카드로 즉시 종료되지 않고 앱의 기본 화면(예: MessageList)으로 이동합니다. 다시 스와이프하면 카드로 돌아갑니다.

카드 내에서 상태 업데이트

카드에는 키-값 쌍을 저장하고 새로고침 시에도 유지되는 StateBuilders.State 객체가 있습니다. loadAction()를 사용하여 사용자가 카드와 상호작용할 때 이 상태를 업데이트할 수 있습니다.

이렇게 하려면 새 상태 값이 포함된 DynamicDataMaploadAction()에 전달합니다.

textButton(
    labelContent = {
        text("loadAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        loadAction(
            dynamicDataMapOf(
                stringAppDataKey("name") mapTo "Javier",
                intAppDataKey("age") mapTo 37,
            )
        )
    ),
)

이 작업으로 인해 onTileRequest()가 트리거되면 requestParams.currentState.stateMap에서 업데이트된 데이터를 읽을 수 있습니다. 이는 카운터 증분 또는 설정 전환과 같이 카드의 데이터를 직접 수정하는 상호작용에 유용합니다.

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {

    // When triggered by loadAction(), "name" will be "Javier", and "age" will
    // be 37.
    with(requestParams.currentState.stateMap) {
        val name = this[stringAppDataKey("name")]
        val age = this[intAppDataKey("age")]
    }

    // ...
}