본문 바로가기
Android

[ Android ] Android에서 Selector 사용 시 상태 정의 순서의 중요성 이해하기

by quessr 2024. 3. 26.

 

Android에서 selector를 사용하는 것은 버튼이나 뷰의 다양한 상태(예: 선택됨, 클릭됨, 포커스됨 등)에 따라 다른 그래픽이나 색상을 표시할 수 있게 해 주는 유용한 기능이다.
selector는 XML 파일로 정의되며, <selector> 태그 내에 여러 <item> 태그를 사용하여 각 상태에 대한 디자인을 지정하고,
각 <item> 태그는 특정 상태에 대응하는 그래픽 리소스를 지정한다.

오늘 기록 해 두고 싶은 내용은 selector를 사용할 때 상태 정의 순서의 중요성에 관한 것 이다.

평소에는 selector를 만들고 사용하는 데 큰 신경을 쓰지 않았었는데, 평소와 같이 버튼의 selector를 만들고 테스트를 해보니,
selected와 enabled의 상태가 전혀 적용되지 않는 문제에 직면했다.

코드를 아무리 살펴봐도 문제가 없어 보였기에, 이상하게 생각하며 원인을 찾기 위해 여러 시도를 해 보았다.
그 과정에서 문제의 핵심이 selector에서의 상태 정의 순서에 있음을 발견했다.

selector를 만들고 사용하는 과정에서, 상태 정의 순서의 중요성을 간과하기 쉽다고 생각한다.

다음과 같은 순서로 상태를 정의했을 때 문제가 발생 할 수 있다.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 기본 상태 -->
    <item android:drawable="@drawable/button_normal"/>
    <!-- 버튼이 눌렸을 때의 상태 -->
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed" />
    <!-- 버튼이 선택되었을 때의 상태 -->
    <item android:state_selected="true" android:drawable="@drawable/button_selected"/>
</selector>


Android 시스템은 selector XML 파일을 처리할 때 파일을 위에서 아래로 읽는다.
시스템은 첫 번째로 일치하는 상태를 발견하면 해당 <item>을 적용하고 검색을 중단한다.
이로 인해, 더 구체적인 상태를 나타내는 <Item>을 파일 상단에 위치시키고, 더 일반적인 상태(기본상태)를 나타내는 <Item>은 파일 하단에 위치시켜야 한다.
이렇게 함으로써, 더 구체적인 상태가 더 일반적인 상태보다 우선 적용되도록 할 수 있는 것이다.

문제의 해결을 위해 정의 순서를 다음과 같이 변경했다.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 버튼이 눌렸을 때의 상태 -->
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed" />
    <!-- 버튼이 선택되었을 때의 상태 -->
    <item android:state_selected="true" android:drawable="@drawable/button_selected"/>
    <!-- 기본 상태 (더 일반적인 상태이므로 마지막에 위치) -->
    <item android:drawable="@drawable/button_normal"/>
</selector>

 

이 변경을 통해 selected와 enabled 상태가 올바르게 적용되는 것을 확인할 수 있었다.