본문 바로가기
Android/이것저것

[Android] 터치 영역 넓히기

by 일상 속 둔치 2023. 3. 26.

Android 개발을 하다보면 심심치 않게 UI/UX 가이드에 따라서 터치 영역을 조절 해야할 때가 있다.

*  Material에서는 터치 대상이 최소 48*48 dp 이상에 터치 대상끼리 8dp는 떨어져 있어야한다고 함

 

필자의 경우에도 UX팀에서 사용성을 위해서 버튼 터치 영역을 늘려달라는 요청이 있었다.

 

무튼... 터치 영역을 넓히는 몇가지 방법(?)을 생각해보자.

Android 개발자 설정에서 레이아웃 보기를 설정하면 터치 영역을 단말에서 확인할 수 있다.

 

Padding 지정

가장 쉽고 흔하게 사용되는 방법이다.

Padding까지가 View의 영역으로 인식 되기 때문에 간단하게 Touch 영역을 넓힐 수 있다.

그러나 단점으로는 기존의 View가 흐트러 질 수 있다는 점이다.

그래도 잘 계산해서 이 방법으로 해결이 된다면 제일 좋은 경우지 않을까 싶다.

 

Touch Delegate

부모 View가 자식 View의 터치 영역을 커스텀 할 수 있게 하는 클래스다.

대부분의 경우에 유용하게 사용할 수 있을 것 같다.

    public class MainActivity : Activity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            findViewById<View>(R.id.parent_layout).post {
                val delegateArea = Rect()
                val myButton = findViewById<ImageButton>(R.id.button).apply {
                    isEnabled = true
                    setOnClickListener {
                        Toast.makeText(
                                this@MainActivity,
                                "Touch occurred within ImageButton touch region.",
                                Toast.LENGTH_SHORT
                        ).show()
                    }

                    getHitRect(delegateArea)
                }

                delegateArea.right += 100
                delegateArea.bottom += 100

                (myButton.parent as? View)?.apply {
                    touchDelegate = TouchDelegate(delegateArea, myButton)
                }
            }
        }
    }

 

사용법은 간단하다.

1. getHitRect로 부모 영역에 지정된 확장하고자 하는 View의 터치 영역을 가져온다.

val delegateArea = Rect()
myButton.getHitRect(delegate)

2. 수정하고 싶은 크기 만큼 Rect 영역을 수정해준다.

* Android는 왼쪽이 x좌표 시작, 위쪽이 y좌표 시작이다

delegateArea.right += <value>
delegateArea.bottom += <value>

3. 부모 View에 TouchDelegate를 지정해준다.

(myButton.parent as? View)?.apply{
	touchDelegate = TouchDelegate(delegateArea, myButton)
}

 

View

Touch Delegate는 결국 상위 View의 영역을 넘어서는 지정할 수 없다.

* 하위 View의 터치 영역을 상위 View에 지정해주는 것이기 때문

 

그런데 요구 사항에 따라 상위 View를 넘어서는 터치 영역을 지정해야하는 경우가 생긴다.

여러 방법이 있겠지만 View가 복잡한 경우 상위에 Touch를 위한 View를 생성하고 Touch 했을 때의 동작을 해당 view에서 수행하거나 하위 View로 event를 전달하는 방식으로도 해결할 수 있다.

 

실제로 업무를 하다보면 항상 정석적인 방법만 고수 할 수는 없는 것 같다.

예를 들어 긴급으로 릴리즈를 해야하는 경우 충분한 시간을 가지고 검증을 하기 어렵다.

이럴 때에 변경에 대해서 굉장히 보수적으로 접근하게 된다.

고급 프로그래머라면 정석적이거나 현명한 방법으로 문제를 해결하겠지만... 필자 같은 주니어 개발자는 조오금 어려운 부분이 있다.

따라서 빠른 이슈 해결/사이드 이펙트 방지를 위해서 정석적이지 않은 치팅 같은 방법을 채택하는 경우도 심심찮게 있다.

물론, 긴급 이슈 해결 후에 refactoring이 가능한 부분이라면 수정해주는 부분이 좋을 것이다


 

Material Design

Build beautiful, usable products faster. Material Design is an adaptable system—backed by open-source code—that helps teams build high quality digital experiences.

m3.material.io

 

TouchDelegate  |  Android Developers

 

developer.android.com

댓글