[Jetpack Compose] clickable 클릭 효과 커스텀 하게 설정하기 : Custom Indication 구현하기

2023. 7. 17. 21:00· Android Jetpack Compose/Compose Modifier
목차
  1. clickable의 기본 클릭 효과 살펴보기
  2. clickable에 클릭 효과 커스텀 하게 설정하기
  3. Indication 상속해 커스텀 클릭 효과 만들기 
  4. CustomIndication clickable에 적용하기
반응형

clickable의 기본 클릭 효과 살펴보기

이전 글에서 clickable의 기본 클릭 효과가 매우 어색한 것을 보았다. 이것이 왜 어색하게 느껴졌는지 구현체를 보면서 살펴보도록 하자. 만약 우리가 clickable { } 형태로 클릭 이벤트를 처리한다면 이 내부에서는 DefaultDebugIndication이란 클릭 효과를 사용한다. 그리고 이 클릭 효과는 아래와 같이 구현되어 있다.

 

private object DefaultDebugIndication : Indication {

    private class DefaultDebugIndicationInstance(
        private val isPressed: State<Boolean>,
        private val isHovered: State<Boolean>,
        private val isFocused: State<Boolean>,
    ) : IndicationInstance {
        override fun ContentDrawScope.drawIndication() {
            drawContent()
            if (isPressed.value) {
                drawRect(color = Color.Black.copy(alpha = 0.3f), size = size)
            } else if (isHovered.value || isFocused.value) {
                drawRect(color = Color.Black.copy(alpha = 0.1f), size = size)
            }
        }
    }

    @Composable
    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
        val isPressed = interactionSource.collectIsPressedAsState()
        val isHovered = interactionSource.collectIsHoveredAsState()
        val isFocused = interactionSource.collectIsFocusedAsState()
        return remember(interactionSource) {
            DefaultDebugIndicationInstance(isPressed, isHovered, isFocused)
        }
    }
}

 

위 코드를 보면 다음의 3가지 이벤트를 감지한다. interactionSource로부터 collectIsPressedAsState를 통해 눌림 효과를 감지하고, collectIsHoveredAsState를 통해 왔다갔다 하는 효과를 감지하며, collectAsFocusedAsState를 통해 컴포저블이 포커싱 되었는지에 대해 감지한다.

 

그리고 만약 눌림 효과가 발생했을 때는 drawRect(color = Color.Black.copy(alpha = 0.3f), size = size) 를 통해 alpha(불투명도)가 0.3인 검은색 사각형을 눌린 컴포저블 위에 그리고, hovered 되거나 포커스 되었을 때는 alpha가 0.1인 검은색 사각형을 해당 이벤트가 발생한 컴포저블 위에 그리는 형태로 Indication을 만든다.

 

이로 인해 아래와 같이 뚝뚝 끊기는 것 같은 효과가 나타나게 된다.

 

이를 해결하기 위해서는 불투명도(alpha)를 줄여 Indication의 색상을 조금 더 연하게 하거나 눌렸을 때 alpha값이 서서히 변화하도록 애니메이션을 주어야 한다. 

 

애니메이션까지 다루기에는 글이 복잡해지므로, 이번 글에서는 새로운 Indication을 간단히 구현하는 방법에 대해서만 살펴본다.

 

 

clickable에 클릭 효과 커스텀 하게 설정하기

clickable에 클릭 효과를 커스텀하게 설정하기 위해서는 다음 clickable 함수를 사용해야 한다. 이 clickable 함수에서 중요한 파라미터는 interationSource, indication, onClick 세가지이다.

fun Modifier.clickable(
    interactionSource: MutableInteractionSource,
    indication: Indication?,
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit
)

 

interactionSource는 유저의 이벤트를 받아오는데 필요한 객체이며, indication은 클릭 효과를 만들 수 있는 객체, onClick은 클릭이 일어났을 때 동작을 설정할 수 있는 파라미터이다.

 

Indication 상속해 커스텀 클릭 효과 만들기 

먼저 CustomIndication부터 다음과 같이 만든다.

object CustomIndication : Indication {
    private class DefaultDebugIndicationInstance(
        private val isPressed: State<Boolean>,
    ) : IndicationInstance {
        override fun ContentDrawScope.drawIndication() {
            drawContent()
            if (isPressed.value) {
                drawRect(color = Color.Gray.copy(alpha = 0.1f), size = size)
            }
        }
    }

    @Composable
    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
        val isPressed = interactionSource.collectIsPressedAsState()
        return remember(interactionSource) {
            DefaultDebugIndicationInstance(isPressed)
        }
    }
}

이 CustomIndication은 기존 DefaultDebugIndication에 비해 클릭 이벤트를 처리하는 성능이 좋다 이유는 유저가 화면을 누른 이벤트만 처리하기 때문이다. 또한 화면이 눌렸을 때, 위에 alpha값이 0.1인 회색(Gray)을 그려서 이전보다 클릭 효과가 자연스러워진다.

 

CustomIndication clickable에 적용하기

Custom Indication은 Clickable에 다음과 같이 적용될 수 있다.

Box(
    modifier = Modifier
        .size(300.dp)
        .background(Color.Blue)
        .clickable(
            interactionSource = remember{ MutableInteractionSource() },
            indication = CustomIndication
        ) {
            Toast.makeText(baseContext, "조세영의 Kotlin World", Toast.LENGTH_SHORT).show()
        }
)

여기서 interactionSource는 한 번만 만들어져야 하고, Recompose될 때마다 매번 새로 만들어지면 안되므로 remember을 통해 한번 만들어지도록 한다. 이후 indication에 위해서 만든 CustomIndication 객체를 넘긴 후 클릭 이벤트를 설정한다. 그려면 클릭 이벤트는 다음과 같이 보여진다.

이전 클릭 효과에 비해 매우 자연스러워 진 것을 볼 수 있다.

 

위와 같이 Indication을 상속하는 객체를 만들어 클릭 효과를 자연스럽게 만들 수 있는 다양한 방법이 존재한다. 한 번 시도해보자.

반응형
저작자표시 비영리 변경금지
  1. clickable의 기본 클릭 효과 살펴보기
  2. clickable에 클릭 효과 커스텀 하게 설정하기
  3. Indication 상속해 커스텀 클릭 효과 만들기 
  4. CustomIndication clickable에 적용하기


 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com

'Android Jetpack Compose/Compose Modifier' 카테고리의 다른 글
  • [Android Compose] Composable에 Content Description 붙이기
  • [Jetpack Compose] clickable 클릭 효과 제거하기 : Ripple 효과 제거하기
  • [Jetpack Compose] clickable 사용해 유저 클릭 이벤트 감지하기
  • [Android Compose Modifier] 7. padding과 border을 조합하여 중첩 테두리 만들기(Multiple Border)
Dev.Cho
Dev.Cho
'조세영의 Kotlin World'는 Kotlin를 전문적으로 다루는 개인 기술 블로그입니다. Kotlin 세계에 대한 양질의 자료를 제공하며 Kotlin, Android, Spring, CI, CD 분야에 대해 다룹니다.
Dev.Cho
조세영의 Kotlin World
Dev.Cho
전체
오늘
어제

블로그 메뉴

  • LinkedIn
  • GitHub
  • 분류 전체보기 (491)
    • Kotlin (104)
      • Class and Interface (19)
      • Variable and Function (8)
      • Modifier (5)
      • Collection (14)
      • Time (8)
      • 동시성 제어 (7)
      • Reactive Programming (2)
      • Paradigm (2)
      • Kotlin 자료구조 (15)
      • Design Patterns (11)
      • Algorithm (3)
      • Exception (1)
      • 기타 (9)
      • Update History (0)
    • Coroutines (32)
      • Coroutine Basics (18)
      • Flow (9)
      • CoroutineScope (3)
      • Debugging (2)
    • Testing Codes (28)
      • Test 기본 (3)
      • JUnit5 (9)
      • MockK (6)
      • Testing Coroutines (1)
      • Testing Android (8)
      • Test 기타 (1)
    • Spring (50)
      • Dependency Injection (18)
      • Settings (5)
      • REST API (0)
      • DevTools (1)
      • MVC (18)
      • Error (2)
      • MongoDB (2)
      • Database (4)
    • Android (39)
      • Architecture (2)
      • Component (5)
      • Manifest (1)
      • Lifecycle (2)
      • Dependency Injection (17)
      • Resource (1)
      • Storage (1)
      • Security and Optimization (1)
      • WebView (2)
      • Error (6)
    • Android Jetpack Compose (33)
      • Compose (6)
      • Compose Modifier (13)
      • Compose Resource (4)
      • Compose State (4)
      • Compose Side Effect (6)
    • Android Jetpack Compose UI (48)
      • Compose Layout (14)
      • Compose Text (10)
      • Compose Button (5)
      • Compose Dialog (2)
      • Compose TextField (0)
      • Compose UIs (4)
      • Compose Animation (1)
      • Compose Canvas (12)
    • Android Jetpack (10)
      • Datastore (5)
      • ViewModel (4)
      • LiveData (1)
      • Paging (0)
    • KMP (5)
    • Programming (4)
    • Machine (9)
      • JVM (7)
      • Linux (2)
    • CI, CD (74)
      • Gradle (12)
      • Groovy Gradle (5)
      • Git (25)
      • Git Remote (5)
      • GitHub (5)
      • GitHub Actions (21)
    • Network (33)
      • GraphQL (12)
      • HTTP (11)
      • Basic (9)
    • 오픈소스 (3)
    • Database (3)
      • MongoDB (3)
    • IDE (6)
      • Android Studio (2)
      • Intellij (4)
    • Firebase (1)
    • Javascript (9)

공지사항

  • 코틀린 코루틴 완전 정복 강의 in 인프런 오픈
  • 코틀린 코루틴의 정석 책 출간
  • Kotlin Coroutines 공식 기술 문서 한국어 번⋯
  • GitHub에서 조세영의 Kotlin World를 Foll⋯
  • 문의&제안

인기 글

태그

  • junit5
  • junit
  • Android Compose
  • junit4
  • GraphQL
  • 코루틴
  • 스프링
  • kotlin spring
  • Jetpack Compose
  • 코틀린
  • flow
  • Spring
  • java
  • gradle
  • Spring boot
  • Unit Testing
  • compose
  • github
  • 의존성 주입
  • Coroutine
  • 유닛 테스팅
  • dagger2
  • Class
  • GIT
  • 안드로이드
  • Kotlin
  • Android
  • HTTP
  • Dependency Injection
  • github actions

최근 글

반응형
hELLO · Designed By 정상우.v4.3.0
Dev.Cho
[Jetpack Compose] clickable 클릭 효과 커스텀 하게 설정하기 : Custom Indication 구현하기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.