포커스에 반응
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
포커스 시각화를 위한 시각적 단서 제공
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-27(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-27(UTC)"],[],[],null,["# React to focus\n\nProvide visual cues for easier focus visualization\n--------------------------------------------------\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/dd30aee903e8c247786c064faab1a9ca8d10b46e/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\n### Implement 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/dd30aee903e8c247786c064faab1a9ca8d10b46e/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/dd30aee903e8c247786c064faab1a9ca8d10b46e/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/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/touchinput/focus/FocusSnippets.kt#L485-L497\n ```\n\nUnderstand the state of the focus\n---------------------------------\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\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)"]]