<목차>
- 대표적인 이벤트 -
- 터치 이벤트 -
- 제스처 이벤트 -
- 키 이벤트 -
위임 모델(Delegation Model) : 이벤트를 객체에 전달한 후 이후의 처리 과정을 버튼에 위임하는 이벤트 처리 방식.
각각의 이벤트를 처리할 수 있는 리스너(Listener) 인터페이스를 등록할 수 있도록 함.
대표적인 이벤트
- 터치 이벤트 : 화면을 손가락으로 누를 때 발생
- 제스처 이벤트 : 터치 이벤트 중에서 일정 패턴(ex. 스크롤)으로 구분되는 이벤트
- 키 이벤트 : 키패드나 하드웨어 버튼을 누를 때 발생
- 포커스 : 뷰마다 순서대로 주어지는 포커스
- 화면 방향 변경 : 화면 방향(가로/세로)이 바뀜에 따라 발생
터치 이벤트
다음과 같은 레이아웃을 만들었다. 일단 view, scrollView만 활용한다. (view2는 제스처 이벤트)
scrollView 안에 터치 상태와 해당 좌표를 출력할 수 있도록 textView를 배치했다.
<mainActivity.java 코드>
package com.example.chapter33;
public class MainActivity extends AppCompatActivity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.textView);
View view = findViewById(R.id.view);
view.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("손가락 눌림 : "+curX+", "+curY);
}
else if(action==MotionEvent.ACTION_MOVE){
println("손가락 움직임 : "+curX+", "+curY);
}
else if(action==MotionEvent.ACTION_UP){
println("손가락 뗌 : "+curX+", "+curY);
}
return true;
}
});
}
public void println(String data){
textView.append(data+"\n");
}
}
setOnTouchListener 메서드를 호출하여 리스너 등록. OnTouchListener 객체를 생성하면서 전달한다.
view.setOnTouchListener(new View.OnTouchListener()
motionEvent 객체의 터치 상태, X/Y 좌표는 getAction(), getX(), getY()을 통해 값을 얻을 수 있다.
이때 getAction 메서드에서 반환되는 값을 통해 터치 상태를 파악할 수 있다.
MotionEvent.ACTION_DOWN : 손가락이 눌렸을 때
MotionEvent.ACTION_MOVE : 손가락이 눌린 상태로 움직일 때
MotionEvent.ACTION_UP : 손가락이 떼졌을 때
마지막의 println 함수는 단순히 해당 상태를 textview에 출력하기 위해 만들어졌다.
textView에 텍스트를 넣는 방법은 setText 또는 append가 있는데
setText는 기존에 있는 텍스트를 지우고 새로 들어갈 텍스트를 넣는 반면
append는 기존에 있는 텍스트에 추가로 텍스트를 넣는다.
<실행화면>
분홍색 뷰에 터치를 하면 아래 텍스트뷰(스크롤 가능)에 상태와 좌표가 출력된다.
제스처 이벤트
GestureDetector : 제스처 이벤트를 처리해주는 클래스
detector new GestureDetector(this, new GestureDetector.OnGestureListener(){}
이 코드를 추가하면 알아서 아래와 같이 제스처 동작에 따른 메서드가 생성됨.
제스처 이벤트의 종류는 아래와 같다.
onDown() : 화면이 눌렸을 경우
onShowPress() : 화면이 눌렸다 떼어진 경우
onSingleTapUp() : 화면이 한 손가락으로 눌렸다 떼어진 경우
onSingleTapConfirmed() : 화면이 한 손가락으로 눌려지는 경우
onDoubleTap() : 화면이 두 손가락으로 눌려지는 경우
onDoubleTapEvent() : 화면이 두 손가락으로 눌려진 상태에서 떼거나 이동하는 등 세부적인 액션을 취하는 경우
onScroll() : 화면이 눌린 채 일정한 속도와 방향으로 움직였다 떼는 경우
onFling() : 화면이 눌린 채 가속도를 붙여 손가락을 움직였다 떼는 경우 (=빠른 속도로 스크롤)
onLongPress() : 화면을 손가락으로 오래 누르는 경우
위에 자동생성되는 함수들 보면 onDoubleTap, onDoubleTapEvent 빼고 다 생성됨. (더블탭은.. 지도나 리듬게임 말고는 사용을 많이 안해서 그런건가)
<mainActivity.java 코드 (위에서 만든 코드에 추가)>
package com.example.chapter33;
public class MainActivity extends AppCompatActivity {
TextView textView;
GestureDetector detector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.textView);
View view = findViewById(R.id.view);
view.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("손가락 눌림 : "+curX+", "+curY);
}
else if(action==MotionEvent.ACTION_MOVE){
println("손가락 움직임 : "+curX+", "+curY);
}
else if(action==MotionEvent.ACTION_UP){
println("손가락 뗌 : "+curX+", "+curY);
}
return true;
}
});
detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(@NonNull MotionEvent motionEvent) {
println("onDown() 호출");
return true;
}
@Override
public void onShowPress(@NonNull MotionEvent motionEvent) {
println("onShowPressed() 호출");
}
@Override
public boolean onSingleTapUp(@NonNull MotionEvent motionEvent) {
println("onSingleTapUp() 호출");
return true;
}
@Override
public boolean onScroll(@Nullable MotionEvent motionEvent, @NonNull MotionEvent motionEvent1, float v, float v1) {
println("onScroll() 호출 : "+v+", "+v1);
return true;
}
@Override
public void onLongPress(@NonNull MotionEvent motionEvent) {
println("onLongPress() 호출");
}
@Override
public boolean onFling(@Nullable MotionEvent motionEvent, @NonNull MotionEvent motionEvent1, float v, float v1) {
println("onFling() 호출 : "+v+", "+v1);
return true;
}
});
View view2 = findViewById(R.id.view2);
view2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
detector.onTouchEvent(motionEvent);
return true;
}
});
}
public void println(String data){
textView.append(data+"\n");
}
}
onScroll()과 onFling()에서 v와 v1은 각각 손가락이 x축과 y축으로 움직인 속도이다.
<문제 해결>
아니 에러가 계속 떠서 인터넷에 검색해봐도 해결이 안되는거다. 1시간 넘게 여기에 매달렸음.
문제 발생 1. detector에서 Not a statement라는 에러가 뜸
not a statement란 명령문이 아니라는 뜻이다.
아.. '='을 까먹었다. 슈바
문제 발생 2. SetOnTouchListener 메소드를 찾을 수 없다고 뜸
왜냐면 S로 시작하는 게 아니라 s로 시작하니까. 슈바!!! (진짜 짜증)
아니 몇번씩이나 코드 보면서 뭐가 이상한가.. 계속 봤는데 왜 눈치채지 못한거지? 아... 짜증짜증
<실행화면>
1. 오른쪽으로 스크롤했을 때 : onDown() -> onScroll() -> onFling()
2. 가볍게 터치했을 때 : onDown() -> onSingleTapUp()
3. 길게 터치했을 때 : onDown() -> onShowPress() -> onLongPress()
와 같은 순서대로 호출되는 것을 볼 수 있다.
키 이벤트
위 코드에다 BACK 버튼(뒤로가기 버튼)을 누르면 토스트를 띄우는 코드를 추가해보았다.
mainActivity에서 우클릭->Generate->Overide Method를 누른 뒤, onKeyDown 메소드를 선택하여 재정의한다.
<mainActivity.java 추가 코드>
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK){
Toast.makeText(this,"시스템 [BACK] 버튼이 눌렸습니다.", Toast.LENGTH_LONG).show();
return true;
}
return false;
}
KEYCODE_BACK이 뒤로가기 버튼을 의미한다.
<키 코드 종류>
KEYCODE_DPAD_LEFT : 왼쪽 화살표
KEYCODE_DPAD_RIGHT : 오른쪽 화살표
KEYCODE_DPAD_UP : 위쪽 화살표
KEYCODE_DPAD_DOWN : 아래쪽 화살표
KEYCODE_DPAD_CENTER : 중앙 버튼
KEYCODE_CALL : 통화 버튼
KEYCODE_ENDCALL : 통화 종료 버튼
KEYCODE_VOLUME_UP : 소리 증가 버튼
KEYCODE_VOLUME_DOWN : 소리 감소 버튼
KEYCODE_0 ~ KEYCODE_9 : 숫자 0~9까지의 키값
KEYCODE_A ~ KEYCODE_Z : 알파벳 A~Z까지의 키값
근데 다른 키에 비해 BACK 버튼이 눌린 경우는 많기에.. BACK 버튼의 경우 좀 더 간단하게 처리할 수 있는 방법이 따로 존재한다. onBackPressed 메서드만 재정의하면 간단하게 이벤트 처리가 가능하다.
<실행화면>
뒤로가기 버튼을 누를 시 위와 같이 토스트가 출력된다.
'TIL > 안드로이드 스튜디오' 카테고리의 다른 글
3장 토스트와 스낵바 (냠냠) (0) | 2024.11.28 |
---|---|
3장 이벤트 처리(방향 전환) / 메소드 재정의는 Ctrl+O! (0) | 2024.11.26 |
에러 (0) | 2024.11.25 |
3장 드로어블 (0) | 2024.11.22 |
3장 기본 위젯 (0) | 2024.11.20 |