티스토리 뷰

Android

2. Event : Touch, Gesture, Key

알 수 없는 사용자 2018. 9. 25. 23:37


이번에는 Event에 대해 알아보겠습니다.

보통 안드로이드 프로그래밍 공부를 시작하면 

처음 배우는게 버튼이벤트 처리라고 생각해요!

버튼이벤트는 어떤 작업을 하더라도 접해볼 경우가 많기 때문에

이번에는 TextView의 터치와 제스터 이벤트에 대해 알아보도록 하겠습니다~


============================================================


Event!? 행사!?



1. event가 무엇일까!?


 사실 보통 event란 단어는 쇼핑몰에서나 할인 이벤트!! 이런 곳에서 찾아보기 쉬운 단어죠!

언뜻 보면 이벤트랑 단어를 프로그래밍 용어에 붙이는게 이상하다고 느껴질 수도 있습니다. 하지만 프로그래밍에서의 이벤트는 크게보면 어떤 사건을 의미하는 단어이기 떄문에 사용되는 것 입니다. 예를 들면' 사용자가 클릭을 했다! '라면 프로그램 입장에서는 어떤 사건이 발생한 것입니다. 그렇기 때문에 event라는 단어를 붙인 것입니다. 


 잡담이지만 안드로이드 프로그래밍을 하면서 흥미를 느끼게된 이유중 하나가 이런 작명센스때문인 것 같습니다. 무언가 이해하기가 어려운 것도 아니고 알고나면 머리에 쏙들어오게 흥미를 느끼게 작명해둔 느낌이였습니다 ㅎㅎ


2. 어떤 이벤트가 있을까!?


 그럼 간단히 어떤 이벤트가 존재하는지 알아보겠습니다.


    - 터치이벤트 : 화면을 손가락으로 누를 때 발생하는 이벤트

    - 키 이벤트 : 키패드나 하드웨어 버튼을 누를 때 발생하는 이벤트

    - 제스처 이벤트 : 터치 이벤트 중에서 스크롤과 같이 일정 패턴으로 구분되는 이벤트

    - 포커스 : 뷰마다 순서대로 주어지는 포커스

    - 화면 방향 변경 : 화면의 방향이 가로/세로로 바뀜에 따라 발생하는 이벤트


 우리가 흔히 볼 수 있는 이벤트 5가지만 정리한 것입니다. 안드로이드에서는 훨~씬 많은 이벤트가 존재하는데 알고싶으시다면 아래 사이트를 참고하세용ㅎㅎ

 https://developer.mozilla.org/en-US/docs/Web/Reference/Events


3. 이벤트가 무엇을 뜻하는진 알겠는데 어떻게 작동되는거지?


 대표적으로 우리가 사용하는 스마트폰은 터치이벤트가 제일 많이 일어날 것이라 생각하는데요 ! 

 사용자입장에서 누르기만 하면 되는 기능이기 때문에 가볍게 생각할 순 있지만 개발자 입장에서는 어떠한 원리로 동작하는지 알고 있어야합니다.


 버튼event로 예를 들어봅시다.

우리는 대개 이런 방식이나 버튼에 정의된 onClick 속성을 이용하여 메소드로 이용하는 2가지 방법을 사용합니다.

Button button = (Button)findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});


위와 같이 리스너를 사용한 경우는 화면에서 발생하는 이벤트를 버튼과 같은 위젯 객체에 전달한 후 그 이후의 처리 과정을 버튼에 위임한다고 하여 위임 모델(Delegation Model)이라고 부릅니다. 

 위임 모델에서는 각각의 이벤트를 처리할 수 있는 리스너 인터페이스를 설정하여 이벤트를 이벤트 루프에서 받아 처리할 때처럼 코드가 복잡해지지 않고 이벤트를 위젯마다 개별적으로 처리하는 객체지향 코드를 만들 수 있습니다.!

[출처] Do it! 안드로이드 앱프로그래밍


 위의 사진이 다이어그램으로 표현한 패턴입니다.

우리가 스마트폰을 사용할 때 버튼을 터치하는 경우만 있는 것이 아니라 뷰에 보이는 모든 것을 터치할 수 있습니다. 그렇다면 이 때 발생되는 리스너가 다르기 때문에 각자의 상황에 맞추어 작동하게 되는거죠!


 View.OnTouchListener : boolean onTouch(View v, MotionEvent event)

 View.OnKeyListener : boolean onKey(View v, int keyCode, KeyEvent event)

 View.OnClickListener : void onClick(View v)

 View.OnFocusChangeListener : void onFocusChange (View v, boolean hasFocus)


OnClickListener는 버튼과 같은 객체에 주로 사용된다면 OnTouchListener는 일반 뷰 객체에도 사용할 수 있습니다.

인자로 받는 MotionEvent가 사용자가 터치할 때 발생되는 이벤트를 받는 것이지요!

OnFocusChangeListener는 뷰에 포커스가 주어지거나 없어질 경우 발생하는 이벤트입니다!




4. 그럼 몇가지 이벤트를 구현해보자!


  저는 터치 이벤트와 제스처 이벤트,키 이벤트를 테스트해보겠습니다!

일단 원리를 이해하셨다면 뭐가 필요할지 감이 오실거 같습니다.

 어떤 방식으로 터치했냐에 따른 출력문을 띄울 텍스트뷰, 사용자의 제스처 터치 이벤트를 받을 뷰, 터치 이벤트를 받을 뷰 이 3가지면 되겠죠 ㅎㅎ



xml은 각자 구성하기에 따름이라 소스는 올리지 않겠습니다 ㅎㅎ

맨 위에 빨간 뷰가 터치 이벤트 뷰, 중간 뷰가 제스쳐 이벤트 뷰, 맨 아래 뷰가 상태에 따른 텍스트가 띄워질 스크롤 뷰를 LinearLayout 형태로 구성했습니다.


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

int state = motionEvent.getAction();

float x = motionEvent.getX();
float y = motionEvent.getY();

if (state == MotionEvent.ACTION_DOWN) {
println("손가락 눌림 : " + x + ", " + y);
} else if (state == MotionEvent.ACTION_MOVE) {
println("손가락 움직임 : " + x + ", " + y);
} else if (state == MotionEvent.ACTION_UP) {
println("손가락 땜 : " + x + ", " + y);
}

return true;
}


});


먼저 터치이벤트를 보기위한 동작코드입니다.

버튼 이벤트를 처리하는 것과 같고 사용한 리스너만 다르다는 것을 볼 수 있죠.

인자로 전달되는 MotionEvent안에 사용자의 상태 정보가 들어있기 때문에 이를 이용해서 사용자가 터치한 상태를 텍스트 뷰로 띄우는 것입니다.

      getAction() 메소드를 이용해 사용자의 상태를 받고 x, y 좌표를 받아 변수에 저장합니다.

      state변수에 int 형태로 담아진 사용자의 상태를 MotionEvent 클래스에 정의된 상수값을 비교하면 사용자의 상태를 알 수 있는 것입니다.

      안드로이드에서는 어떤 상황이나 상태를 int 형태로 처리하여 대부분 판단하는 것 같습니다.

public void println(String data){
textView.append(data +"\n");

이제 textView에 출력문을 띄우면 완성이죠. 

정말 간단하죠? 



제가 누르고 땐 위치를 확인할 수 있습니다. 물론 누른상태에서 움직인다면 움직이는 좌표도 뜨게 됩니다.ㅎㅎ


이제 제스처 이벤트를 해보겠습니다.

 제스처 이벤트는 이벤트 중에서 스크롤 등을 구별한 후에 알려주는 이벤트이기 때문에 제스처 이벤트를 처리해주는 GestureDetector 객체가 필요하게 됩니다.

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

@Override
public void onShowPress(MotionEvent motionEvent) {
println("onShowPress() 호출됨");

}

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

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

@Override
public void onLongPress(MotionEvent motionEvent) {
println("onLongPress() 호출됨");

}

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

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


제스처 이벤트는 구별하기 위한 객체가 필요하다 했으니 객체를 생성합니다.

테스트는 6개의 이벤트 유형만 다루고 있으나 실제로는 9가지의 이벤트 유형이 존재하게 됩니다.

  - onDown() : 화면이 눌렸을 경우

  - onShowPress() : 화면이 눌렸다 떼어지는 경우

  - onSingleTapUp() : 화면이 한 손가락으로 눌렸다 떼어지는 경우

  - onSingleTapConfirmed() : 화면이 한 손가락으로 눌려지는 경우

  - onDoubleTap() : 화면이 두 손가락으로 눌려지는 경우

  - onDoubleTapEvent() : 화면이 두 손가락으로 눌려진 상태에서 떼거나 이동하는 등 세부적인 액션을 취하는 경우

  - onScroll() : 화면이 눌린채 일정한 속도와 방향으로 움직였다 떼는 경우

  - onFling() : 화면이 눌린 채 가속도를 붙여 손가락을 움직였다 떼는 경우

  - onLongPress() : 화면을 손가락으로 오래 누르는 경우


리스너 부분의 코드를 보면 터치 이벤트와 거의 다를 것이 없습니다. 

터치 이벤트는 onTouch메소드에서 바로 출력했다면 제스처이벤트는 제스처 디텍터로 발생하는 터치이벤트를 전달하여 구분하는 것만이 다를 뿐입니다.ㅎㅎ


여러가지 작동을 해보면서 테스트 해봅시다.

에뮬레이터보다는 스마트폰에서 동작하는 것을 추천드려요.


마지막으로 키 이벤트를 해볼꼐요.

키 입력의 경우에는 onKeyDown()과 같은 메소드를 재정의하여 처리할 수 있습니다.

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
Toast.makeText(getApplicationContext(),"시스템 back 버튼이 눌렸습니다.", Toast.LENGTH_LONG).show();
return true;
}
return false;
}

인자로 전달되는 파라미터에서 KeyCode는 어떤 키가 사용되는지 구별할 떄 사용되고 KeyEvent는 키 입력 이벤트에 대한 정보를 알고 싶을 때 사용됩니다.

이런 키 입력 이벤트는 하드웨어 키보드나 소프트 키패드에 상관없이 동일한 이벤트로 전달되며 하드웨어 버튼의 겨웅에도 이 이벤트로 처리할 수 있어요.


 많은 키 값이 있지만 KEYCODE_BACK 코드 값을 이용해 뒤로가기 버튼을 눌렀을 때 toast메시지가 발생하도록 했습니다.


이벤트의 원리를 이해한다면 사용하는 것은 그다지 어렵진 않을 것 같네요 ㅎㅎ

'Android' 카테고리의 다른 글

5. Page Sliding  (0) 2018.09.30
4. Tween Animation  (0) 2018.09.29
3. 액티비티의 수명주기 : Life Cycle  (0) 2018.09.27
1. Toast & Inflation  (0) 2018.09.24
Android Programming 프롤로그  (0) 2018.09.23
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함