관리 메뉴

나만을 위한 블로그

[Android] 화면 터치 여부를 확인하는 법 (dispatchTouchEvent) 본문

Android

[Android] 화면 터치 여부를 확인하는 법 (dispatchTouchEvent)

참깨빵위에참깨빵 2021. 12. 9. 20:11
728x90
반응형

가끔 사용자가 앱 화면을 터치했는지 여부를 확인해야 할 때가 있다.

그래서 처음에 XML에서 레이아웃에 id를 설정하고 클릭 리스너, 터치 리스너를 설정했는데 좀처럼 되지 않았다.

그러다 찾은 것이 DispatchTouchEvent라는 건데, 사용법은 아래와 같다.

 

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;

import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;

public class TestActivity extends AppCompatActivity {

    private final String TAG = this.getClass().getSimpleName();
    ConstraintLayout container;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        container = findViewById(R.id.container_layout);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int userAction = event.getAction();
        switch (userAction) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "화면 누름");
                break;

            case MotionEvent.ACTION_UP:
                Log.e(TAG, "화면에서 손 뗌");
                break;

            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }
}

 

XML에 어떤 뷰도 설정하지 않고 부모 레이아웃에 id만 container_layout으로 설정했기 때문에 XML 코드는 생략한다.

onCreate() 밑을 보면 dispatchTouchEvent()를 재정의하고 사용자 액션에 따라 다른 로그가 찍히도록 한 걸 볼 수 있는데 이 dispatchTouchEvent()가 무엇인지 확인해보자.

 

https://developer.android.com/training/gestures/viewgroup?hl=ko 

 

ViewGroup에서 터치 이벤트 관리  |  Android 개발자  |  Android Developers

ViewGroup에서 터치 이벤트 관리 ViewGroup에서 터치 이벤트를 처리할 때는 특별히 주의해야 합니다. 왜냐하면 ViewGroup에는 ViewGroup과 다른 터치 이벤트의 타겟인 하위 요소가 있는 경우가 흔하기 때문

developer.android.com

...(중략) ViewGroup이 ACTION_OUTSIDE가 포함된 MotionEvent를 수신하면 이벤트는 기본적으로 하위 요소에 전달되지 않는다. ACTION_OUTSIDE가 포함된 MotionEvent를 처리하려면 dispatchTouchEvent(MotionEvent event)를 재정의해서 적절한 View에 전달하거나 관련 Window.callback(예 : Activity)에서 처리한다

 

ACTION_OUTSIDE에 대한 내용은 아래 링크에서 확인할 수 있다.

 

https://developer.android.com/reference/android/view/MotionEvent?hl=ko#ACTION_OUTSIDE 

 

MotionEvent  |  Android Developers

 

developer.android.com

getActionMasked()에 대한 상수 : UI 요소의 일반 경계 외부에서 움직임이 발생했다. 이것은 전체 제스처를 제공하지 않고 움직임, 터치의 초기 위치만 제공한다. 이벤트의 위치는 뷰 계층 구조의 범위를 벗어나므로 기본적으로 ViewGroup의 자식으로 전달되지 않는다. 따라서 ACTION_OUTSIDE를 사용한 이동은 root view 또는 적절한 Window.callback(예 : 액티비티 또는 다이얼로그)에서 처리돼야 한다

UI에서 움직임이나 사용자 터치가 발생하면 이를 감지할 수 있게 해주는 상수값이란 것 같다.

그럼 dispatchTouchEvent()의 원형은 어떻게 되어 있는가?

 

https://developer.android.com/reference/android/view/ViewGroup?hl=ko#dispatchTouchEvent(android.view.MotionEvent) 

 

ViewGroup  |  Android Developers

 

developer.android.com

터치 스크린 모션 이벤트를 대상 뷰로 전달하거나 대상인 경우 이 뷰로 전달한다

이 메서드는 이벤트가 뷰에 의해 처리된 경우 true, 아니면 false를 리턴하는 메서드다. 터치 이벤트를 뷰로 전달하는 역할을 한다.

다시 코드로 돌아가서, dispatchTouchEvent()를 재정의하고 event.getAction()으로 사용자가 어떤 행동을 했는지에 대한 데이터를 가져온다.

그리고 switch문으로 분기시켜서 상수로 정의된 각 이벤트에 따라 다른 로그를 찍게 하는 간단한 코드다. 이걸 응용하면 화면을 터치했을 때, 화면에서 손을 뗐을 때 필요한 기능들을 구현하는 로직을 짤 수도 있다.

반응형
Comments