11/*
2- * Copyright 2023 The Android Open Source Project
2+ * Copyright 2025 The Android Open Source Project
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1414 * limitations under the License.
1515 */
1616
17- @file:Suppress(" DEPRECATION_ERROR" )
18-
1917package com.example.compose.snippets.touchinput.focus
2018
21- import androidx.compose.foundation.Indication
22- import androidx.compose.foundation.IndicationInstance
19+ import androidx.compose.foundation.IndicationNodeFactory
2320import androidx.compose.foundation.background
2421import androidx.compose.foundation.border
2522import androidx.compose.foundation.clickable
2623import androidx.compose.foundation.focusGroup
2724import androidx.compose.foundation.focusable
25+ import androidx.compose.foundation.interaction.FocusInteraction
2826import androidx.compose.foundation.interaction.InteractionSource
2927import androidx.compose.foundation.interaction.MutableInteractionSource
30- import androidx.compose.foundation.interaction.collectIsFocusedAsState
3128import androidx.compose.foundation.layout.Box
3229import androidx.compose.foundation.layout.Column
3330import androidx.compose.foundation.layout.Row
@@ -42,7 +39,6 @@ import androidx.compose.material3.Text
4239import androidx.compose.material3.TextButton
4340import androidx.compose.material3.TextField
4441import androidx.compose.runtime.Composable
45- import androidx.compose.runtime.State
4642import androidx.compose.runtime.getValue
4743import androidx.compose.runtime.mutableStateOf
4844import androidx.compose.runtime.remember
@@ -70,9 +66,13 @@ import androidx.compose.ui.input.key.KeyEventType
7066import androidx.compose.ui.input.key.key
7167import androidx.compose.ui.input.key.onPreviewKeyEvent
7268import androidx.compose.ui.input.key.type
69+ import androidx.compose.ui.node.DelegatableNode
70+ import androidx.compose.ui.node.DrawModifierNode
71+ import androidx.compose.ui.node.invalidateDraw
7372import androidx.compose.ui.platform.LocalFocusManager
7473import androidx.compose.ui.tooling.preview.Preview
7574import androidx.compose.ui.unit.dp
75+ import kotlinx.coroutines.launch
7676
7777@Preview
7878@Composable
@@ -436,45 +436,64 @@ private fun ReactToFocus() {
436436}
437437
438438// [START android_compose_touchinput_focus_advanced_cues]
439- private class MyHighlightIndicationInstance (isEnabledState : State <Boolean >) :
440- IndicationInstance {
441- private val isEnabled by isEnabledState
442- override fun ContentDrawScope.drawIndication () {
439+ private class MyHighlightIndicationNode (private val interactionSource : InteractionSource ) :
440+ Modifier .Node (), DrawModifierNode {
441+ private var isFocused = false
442+
443+ override fun onAttach () {
444+ coroutineScope.launch {
445+ var focusCount = 0
446+ interactionSource.interactions.collect { interaction ->
447+ when (interaction) {
448+ is FocusInteraction .Focus -> focusCount++
449+ is FocusInteraction .Unfocus -> focusCount--
450+ }
451+ val focused = focusCount > 0
452+ if (isFocused != focused) {
453+ isFocused = focused
454+ invalidateDraw()
455+ }
456+ }
457+ }
458+ }
459+
460+ override fun ContentDrawScope.draw () {
443461 drawContent()
444- if (isEnabled ) {
462+ if (isFocused ) {
445463 drawRect(size = size, color = Color .White , alpha = 0.2f )
446464 }
447465 }
448466}
467+
449468// [END android_compose_touchinput_focus_advanced_cues]
450469
451470// [START android_compose_touchinput_focus_indication]
452- class MyHighlightIndication : Indication {
453- @Composable
454- override fun rememberUpdatedInstance (interactionSource : InteractionSource ):
455- IndicationInstance {
456- val isFocusedState = interactionSource.collectIsFocusedAsState()
457- return remember(interactionSource) {
458- MyHighlightIndicationInstance (isEnabledState = isFocusedState)
459- }
471+ object MyHighlightIndication : IndicationNodeFactory {
472+ override fun create (interactionSource : InteractionSource ): DelegatableNode {
473+ return MyHighlightIndicationNode (interactionSource)
460474 }
475+
476+ override fun hashCode (): Int = - 1
477+
478+ override fun equals (other : Any? ) = other == = this
461479}
462480// [END android_compose_touchinput_focus_indication]
463481
464482@Composable
465483private fun ApplyIndication () {
466484 // [START android_compose_touchinput_focus_apply_indication]
467- val highlightIndication = remember { MyHighlightIndication () }
468485 var interactionSource = remember { MutableInteractionSource () }
469486
470487 Card (
471488 modifier = Modifier
472489 .clickable(
473490 interactionSource = interactionSource,
474- indication = highlightIndication ,
491+ indication = MyHighlightIndication ,
475492 enabled = true ,
476493 onClick = { }
477494 )
478- ) {}
495+ ) {
496+ Text (" hello" )
497+ }
479498 // [END android_compose_touchinput_focus_apply_indication]
480499}
0 commit comments