본문 바로가기
Android/Concepts

기본적인 Event 처리 - Touch, Gesture, Key

by JuHy_ 2019. 8. 1.

기본적인 Event 종류

앱을 사용할 때 사용자의 입력이 다양하게 들어오는데 이를 Event라고 한다.

개발자는 이렇게 Event를 통해 들어온 정보를 바탕으로 여러 가지 기능을 만들 수 있다.

그러기 위해서는 Event 발생 시 실행될 함수를 만들고 그 함수를 Listener에 넣어주어야 한다.

 

그렇다면 기본적인 Event로

1. 사용자가 화면을 Touch했을 때

2. 드래그 등의 Gesture를 입력했을 때

3. 키를 입력했을 때

각각의 처리 방법을 알아보자.

 

Touch Event

사용자가 특정한 View를 터치했을 때 어떤 action을 했는지 기록하는 기능을 만들어보자.

View view1 = findViewById(R.id.view1);
view1.setOnTouchListener(new View.OnTouchListener() {
	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {

		int action = motionEvent.getAction();
		float curX = motionEvent.getX();
		float curY = motionEvent.getY();

		if(action==MotionEvent.ACTION_DOWN){
			println("Touch down : " + curX + ", " + curY);
		} else if (action==MotionEvent.ACTION_MOVE){
			println("Touch move : " + curX + ", " + curY);
		} else if (action==MotionEvent.ACTION_UP){
			println("Touch up : " + curX + ", " + curY);
		}

		return true;
	}
});

먼저 해당하는 view를 가져오고 setOnTouchListener를 통해 사용자가 터치할 때 반응하기 위한 Listener를 등록해준다.

new View.OnTouchListener를 통해 Listener를 생성할 때에는 안에 onTouch라는 터치 이벤트 발생 시 실행될 코드를 저장할 함수가 꼭 필요하다. 이런 내용들은 안드로이드 스튜디오에서 자동완성을 해주니 이용하도록 하자.

 

onTouch 함수에는 파라미터로 motionEvent 객체를 주는데 이 안에 사용자의 action 정보가 저장되어 있다.

motionEvent.getAction()은 사용자의 action 즉, 터치를 시작하거나 움직이거나 종료한 정보를 반환해준다.

motionEvent.getX()와 getY()는 사용자가 터치하는 위치를 반환해준다.

 

그리고 마지막에 기본적으로 return false로 되어있는 반환값을 return true로 바꿔주어야 정상적으로 처리된다.

 

코드를 실행해보면 위와 같이 사용자가 터치를 시작하고 움직이며 종료한 위치가 기록된 것을 볼 수 있다.

이 외에도 목적에 따라 코드를 바꾸어 다양한 기능을 구현할 수 있다.

 

Gesture Event

Gesture Event는 기본적으로 GestureDetector라는 객체를 통해 사용자의 Gesture를 판단한다.

GestureDetector 안에 사용자의 action에 따라 Gesture가 인식되면 호출되는 함수를 정의할 수 있다.

어떤 함수가 어떨 때 호출되는 지 코드를 통해 알아보자.

 

detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
    @Override
    public boolean onDown(MotionEvent motionEvent) {
        println("onDown() called");
        return true;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
        println("onShowPress() called");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        println("onSingleTapUp() called");
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        println("onScroll() called"+v+", "+v1);
        return true;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
        println("onLongPress() called");
    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        println("onFling() called : "+v+", "+v1);
        return true;
    }
});

onTouchListener와 다르게 onGestureListener 안에는 많은 함수가 있는 것을 볼 수 있다.

 

onDown() : 터치가 시작됐을 때 호출

onShowPress() : onDown()보다 조금 더 오래 터치 시 호출

onLongPress() : onShowPress()보다 조금 더 오래 터치 시 호출

 

onSingleTapUp() : 사용자가 가볍게 터치 후 떼었을 때 호출

 

onScroll(): 사용자가 터치한 상태로 움직였을 때(Drag) 호출

onFling(): 사용자가 터치한 상태로 빠르게 움직였을 때(Swipe) 호출

 

onScroll()과 onFling()에서 v와 v1은 각각 손가락이 x축과 y축으로 움직인 속도이다.

 

이와 같이 GestureDetector 객체를 생성하여 각각의 Gesture 시 실행될 코드를 정의해준 뒤

 

View view2 = findViewById(R.id.view2);
view2.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        detector.onTouchEvent(motionEvent);
        return true;
    }
});

onTouchListener의 onTouch 함수 안에서 detector.onTouchEvent를 호출하여 터치 정보를 넘겨주어야 한다.

이를 통해 Gesture는 결국 TouchEvent를 통해 들어온 정보로 판단한다는 것을 알 수 있다.

 

코드를 실행해보면

1. 오른쪽으로 스크롤했을 때 : onDown() -> onScroll() -> onFling()

2. 가볍게 터치했을 때 : onDown() -> onSingleTapUp()

3. 길게 터치했을 때 : onDown() -> onShowPress() -> onLongPress()

와 같은 순서대로 호출되는 것을 볼 수 있다.

 

Key Event

Key Event는 키패드 뿐만 아니라 디바이스에 장착된 버튼을 눌렀을 때를 말한다.

 

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    if(keyCode==KeyEvent.KEYCODE_BACK){
        println("BackButton Down");
        return true;
    }

    return false;
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {

    if(keyCode==KeyEvent.KEYCODE_BACK){
        println("BackButton Up");
        return true;
    }

    return false;
}

이와 같이 onKeyDown은 키가 눌렸을 때, onKeyUp은 키가 떼졌을 때 호출되며

파라미터로 넘겨받은 keyCode를 통해 입력이 들어온 키를 확인할 수 있다.

따라서 if(keycode==KeyEvent.원하는KEYCODE)와 같이 조건문을 통해 특정 키의 입력에 따라 기능을 구현할 수 있다.

 

※ 이 때 return true로 반환하면 원래 키를 눌렀을 때의 기능 대신 구현한 코드가 동작되므로 주의해야 한다.

 

코드를 실행한 뒤 뒤로가기 버튼을 누르면 위와 같이 눌렸다 떼진 기록이 남는 것을 볼 수 있다.

그리고 원래 뒤로가기를 눌렀을 때 activity가 종료되야 하지만 종료되지 않는 것 또한 볼 수 있다.

 

이 외에도 다양한 KeyCode를 사용하여 많은 기능들을 구현할 수 있다.

 

 

Reference

[부스트코스]안드로이드 프로그래밍

https://www.edwith.org/boostcourse-android

'Android > Concepts' 카테고리의 다른 글

Dialog 사용법 - AlertDialog  (0) 2019.08.02
Toast 사용법 + Snackbar  (0) 2019.08.02
ScrollView 사용법  (0) 2019.07.30
TableLayout 사용법  (0) 2019.07.30
기본적인 Drawable 사용법 - Selector, Shape  (0) 2019.07.18