안드로이드 사용자 터치 Pressed에 대한 처리 방법



모바일 앱 특히 안드로이드 앱에서는 사용자의 액션에 대해서 즉각적인 피드백이 필요하다. 이러한 피드백은 안드로이드의 Selector를 통해 쉽게 구현이 가능하다. Selector는 특정 상태에 따라 설정한 Color값이나 Drawable로 변경해주는 안드로이드만의 가장 강력한 기능이다. 좀 더 알고 싶으면 이전에 작성한 글(안드로이드 Selector에서 Custom States 만들기)을 참고하기 바란다.  

보통 안드로이드의 Pressed에 대한 처리는 레이아웃이나 뷰에서 Background의 Selector기능을 가진 Drawable로 처리하게 된다. Background로 처리하게 되면 레이아웃의 자식뷰들은 Selector의 색상이 가려져 뒷배경만 바껴 보이지 않게 된다. 자식뷰가 레이아웃과 동일한 크기를 가지는 경우에는 거의 표시 되지 않는것과 다름이 없을 정도로 눈에 보이지 않을 수 있다.

Background를 통해 Pressed이미지 처리하는 앱을 한번 살펴 보자. 위의 앱은 안드로이드 다음사전앱이다. 왼쪽 화면은 아무것도 하지않은 일반상태이고, 오른쪽 화면은 아이템을 선택하고 있는 상태이다. 이미지가 아이템의 대부분을 차지하고 있기 때문에 백그라운드로 처리시 선택했다는 영역이 가려져 사용자는 눌려졌다고 인지하기 매우 힘든 상황이다. Normal과 Pressed는 컬러값의 많은 차이가 없어 더더욱 Pressed된 것인지 인지하기 어렵다. 

해결방법?

해결방법은 Background가 아닌 Foreground처리하는 것이다. 즉, 배경이 아니라 위쪽을 덮어버리면 된다. 

다행히도 안드로이드에서는 레이아웃 속성에 android:foreground를 제공해준다. 또한 불행하게도 FrameLayout만 해당속성이 작동되며, 가장많이 쓰는 LinearLayout외 다른 레이아웃들은 작동하지 않는다. LinearLayout에는 android:foreground속성이 구현되어 있지 않아 직접 구현해야 한다.(ForegroundLinearLayout이라고 해서 Github에 공개 되어 있으니 참고하기 바란다.)

<ForegroundLinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:foreground="?android:selectableItemBackground">

    <ImageView
        android:id=”@+id/imageview_opaque”
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    ... other views ...

</ForegroundLinearLayout>

<

p style=”text-align: center; clear: none; float: none;”>

Foreground 사용을 가장 잘 보여주는 구글플러스와 E-Trending앱 이다. 이렇게 Foreground를 사용하면 가장 명확하게 사용자 반응에 대한 피드백을 전달할 수 있다. 

ListView, GridView의 경우 보통 아이템의 뷰에서 Background를 처리하는 경우가 많은데 android:listSelector속성을 통해 Drawable를 설정하고, android:drawSelectorOnTop=”true”속성을 설정해 Foreground처리 가능하다.