포커스에 반응
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
포커스 시각화를 위한 시각적 단서 제공
Material 테마의 포커스 가능 요소에는 이미 포커스 스타일이 있지만
배경화면이 테마와 일치하는 경우 시각적 요소를 추가하여
더 쉽게 찾을 수 있습니다. 좋은 해결책은
배경과 대비가 좋은 색상으로 요소를 추가하세요.
var color by remember { mutableStateOf(Color.White) }
Card(
modifier = Modifier
.onFocusChanged {
color = if (it.isFocused) Red else White
}
.border(5.dp, color)
) {}
이 예에서는 remember
을 사용하여 테두리 색상을
리컴포지션되고 요소의 윤곽선은 요소의 윤곽선이
초점을 맞추거나 잃을 수 있습니다.
고급 시각 자료 구현
Jetpack Compose를 사용하면 더 정교하고 고급스러운 시각적 요소도 만들 수 있습니다.
UI와 더 잘 어울리는 큐를 제공합니다.
- 먼저 UI에서 원하는 큐를 시각적으로 그리는
IndicationInstance
를 만듭니다.
private class MyHighlightIndicationNode(private val interactionSource: InteractionSource) :
Modifier.Node(), DrawModifierNode {
private var isFocused = false
override fun onAttach() {
coroutineScope.launch {
var focusCount = 0
interactionSource.interactions.collect { interaction ->
when (interaction) {
is FocusInteraction.Focus -> focusCount++
is FocusInteraction.Unfocus -> focusCount--
}
val focused = focusCount > 0
if (isFocused != focused) {
isFocused = focused
invalidateDraw()
}
}
}
}
override fun ContentDrawScope.draw() {
drawContent()
if (isFocused) {
drawRect(size = size, color = Color.White, alpha = 0.2f)
}
}
}
- 다음으로,
Indication
를 만들고 포커스가 맞춰진 상태를 기억합니다.
object MyHighlightIndication : IndicationNodeFactory {
override fun create(interactionSource: InteractionSource): DelegatableNode {
return MyHighlightIndicationNode(interactionSource)
}
override fun hashCode(): Int = -1
override fun equals(other: Any?) = other === this
}
indication()
수정자를 통해 Indication
와 InteractionSource
를 모두 UI에 추가합니다.
var interactionSource = remember { MutableInteractionSource() }
Card(
modifier = Modifier
.clickable(
interactionSource = interactionSource,
indication = MyHighlightIndication,
enabled = true,
onClick = { }
)
) {
Text("hello")
}
포커스 상태 이해하기
일반적으로 포커스 상태가 변경될 때마다 FocusEvent
가 실행됩니다.
트리를 구성하고 focusable()
수정자의 상위 요소는
onFocusChanged()
수정자
포커스의 상태를 알아야 하는 경우 이러한 API를 함께 사용하면 됩니다.
다음과 같이 onFocusChanged
수정자를 사용합니다.
- 수정자가 연결된 컴포저블이
isFocused
이면 true
를 반환합니다.
집중
hasFocus
는 isFocused
와 유사하게 작동하지만 상당한 차이가 있습니다.
현재 요소만 확인하는 것이 아니라 현재 요소 또는 요소의 하나가
집중력 있게
isCaptured
는 포커스가 유지될 때마다 true
를 반환합니다. 이는
TextField
에 잘못된 데이터가 포함되어 있어
다른 요소는 포커스를 지우지 않습니다.
이러한 필드는 아래와 같습니다.
Modifier.onFocusChanged {
val isFocused = it.isFocused
val hasFocus = it.hasFocus
val isCaptured= it.isCaptured
}
드림
추천 서비스
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-28(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-08-28(UTC)"],[],[],null,["Provide visual cues for easier focus visualization\n\nWhile all the focusable elements from Material Theme already have a focus style\nthat matches the theme, you might need to add some visual elements to make the\nfocused element easier to spot. A good solution would be to change the border of\nyour element with a color that has a good contrast with the background:\n\n\n```kotlin\nvar color by remember { mutableStateOf(Color.White) }\nCard(\n modifier = Modifier\n .onFocusChanged {\n color = if (it.isFocused) Red else White\n }\n .border(5.dp, color)\n) {}https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/touchinput/focus/FocusSnippets.kt#L427-L434\n```\n\n\u003cbr /\u003e\n\nIn this example, `remember` is used to store the color of the border across\nrecompositions, and the outline of the element is updated every time the element\ngains or loses focus.\n\nImplement advanced visual cues\n\nWith Jetpack Compose, you can also create more sophisticated and advanced visual\ncues that match better with your UI.\n\n1. First, create an `IndicationInstance` that visually draws the cue you want in your UI: \n\n ```kotlin\n private class MyHighlightIndicationNode(private val interactionSource: InteractionSource) :\n Modifier.Node(), DrawModifierNode {\n private var isFocused = false\n\n override fun onAttach() {\n coroutineScope.launch {\n var focusCount = 0\n interactionSource.interactions.collect { interaction -\u003e\n when (interaction) {\n is FocusInteraction.Focus -\u003e focusCount++\n is FocusInteraction.Unfocus -\u003e focusCount--\n }\n val focused = focusCount \u003e 0\n if (isFocused != focused) {\n isFocused = focused\n invalidateDraw()\n }\n }\n }\n }\n\n override fun ContentDrawScope.draw() {\n drawContent()\n if (isFocused) {\n drawRect(size = size, color = Color.White, alpha = 0.2f)\n }\n }\n }\n https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/touchinput/focus/FocusSnippets.kt#L439-L467\n ```\n2. Next, create an `Indication` and remember the focused state: \n\n ```kotlin\n object MyHighlightIndication : IndicationNodeFactory {\n override fun create(interactionSource: InteractionSource): DelegatableNode {\n return MyHighlightIndicationNode(interactionSource)\n }\n\n override fun hashCode(): Int = -1\n\n override fun equals(other: Any?) = other === this\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/touchinput/focus/FocusSnippets.kt#L471-L479\n ```\n3. Add both the `Indication` and an `InteractionSource` to the UI, via the `indication()` modifier: \n\n ```kotlin\n var interactionSource = remember { MutableInteractionSource() }\n\n Card(\n modifier = Modifier\n .clickable(\n interactionSource = interactionSource,\n indication = MyHighlightIndication,\n enabled = true,\n onClick = { }\n )\n ) {\n Text(\"hello\")\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/touchinput/focus/FocusSnippets.kt#L485-L497\n ```\n\nUnderstand the state of the focus\n\nGenerally, every time a state of the focus changes, a `FocusEvent` is fired up\nthe tree, and the parents of a `focusable()` modifier can listen to it using the\n`onFocusChanged()` modifier.\n\nIf you need to know the state of the focus,you can use these APIs in conjunction\nwith the `onFocusChanged` modifier:\n\n- `isFocused` returns `true` if the composable to which the modifier is attached is focused\n- `hasFocus` works similarly to `isFocused`, but with a substantial difference: rather than checking only the current, it checks if the element or one of its children is focused\n- `isCaptured` returns `true` whenever the focus is held. This happens, for instance, when a `TextField` contains incorrect data, so that trying to focus other elements will not clear the focus.\n\nThese fields are shown below: \n\n Modifier.onFocusChanged {\n val isFocused = it.isFocused\n val hasFocus = it.hasFocus\n val isCaptured= it.isCaptured\n }\n\nRecommended for you\n\n- Note: link text is displayed when JavaScript is off\n- [Change focus behavior](/develop/ui/compose/touch-input/focus/change-focus-behavior)\n- [Material Design 2 in Compose](/develop/ui/compose/designsystems/material)\n- [Handle user input](/develop/ui/compose/text/user-input)"]]