웹/모바일 안드로이드 기초

2.2 이벤트 핸들링

이벤트 구현 방법

사용자 인터페이스에서 이벤트란 버튼, 이미지 혹은 기타 위젯을 사용자가 클릭하거나 터치하는 등의 행위를 말하는 것으로 이벤트 발생시 해당 이벤트를 처리하기 위한 프로그램 코드 구현이 반드시 필요 합니다.

안드로이드 프로그램에서 사용하는 이벤트 구현 방법은 다음과 같습니다.

일반적으로 이벤트 발생은 시점을 알 수 없기 때문에 프로그램에서 이벤트를 확인하는 방법은 적당하지 않습니다. 즉, 특정 위젯에서 이벤트가 발생 했는지 수시로 체크하는 방식(polling)은 비효율적이기 때문에 보통 Observer Pattern이라고 부르는 모델을 사용합니다.

Observer Pattern 은 특정 객체(Event Source, Publisher)에서 이벤트가 발생했는지를 모니터링 하는 객체(Event Handler, Listner)를 별도로 두고 해당 객체에서 이벤트가 발생했을 때 이벤트 알림을 구독한 객체(Subscriber)에게 통지(Notify)하는 방식의 구현 모델을 말합니다.

이때 이벤트 발생시 처리할 코드를 구현한 메서드는 이벤트 핸들러에 의해 호출 되므로 콜백 메서드(Callback Method)라고 합니다.

onClick 속성 사용

2.1 레이아웃 개요에서 살펴본 방법으로 레이아웃 xml 파일에 위젯을 등록하면서 해당 위젯에 대한 속성중 onClick 속성에 클릭 이벤트 발생시 수행할 메서드를 지정하는 방식 입니다.

가장 간편한 방법이며 위젯과 관련한 속성과 이벤트를 한곳에서 확인할 수 있다는 점은 장점입니다. 또한 버튼등의 용도가 단순히 클릭 이벤트에 한정된 경우 Activity 에서 별도의 View 바인딩이 필요 없기 때문에 불필요한 코드를 생략할 수 있습니다.

다만, 처리할 수 있는 이벤트가 click 이벤트에 한정된다는 점과 실제 이벤트가 구현된 코드와 이벤트 호출이 분리 되어 있어 코드 관리가 불편할 수 있다는 부분은 단점이 될 수 있습니다.

예를들어 Activity 코드에 구현된 이벤트 처리 메서드의 경우 별도의 주석이 없으면 해당 메서드가 어느 위젯의 이벤트에 의한 콜백 구현인지 확인하기 어렵습니다.

activity_main.xml

android:onClick="showMsg"

MainActivity.java

public void showMsg(View view) {
  String msg = "Hello World!";
  Toast toast = Toast.makeText(this, msg, duration);
  toast.show();
}

별도의 리스너 클래스 구현

처리를 원하는 이벤트 리스너를 구현한 클래스를 생성하고 추상메서드로 정의된 콜백 메서드를 구현하는 방식 입니다. 안드로이드에서는 이벤트 모니터링과 처리를 담당하는 리스너 인터페이스를 두고 있습니다. 예를들어 버튼등을 클릭할 때 발생하는 이벤트 처리를 위해서는 View 클래스에 정의된 static 인터페이스인 OnClickListener를 구현하는 클래스를 만들면 됩니다.

[그림: 안드로이드 이벤트 처리 개요, 출처: https://developer.android.com/]

별도로 구현된 클래스 이므로 리스너 클래스의 재활용이 용이하므로 반복적이거나 비슷한 처리를 해야한는 이벤트 처리시 코드를 줄일 수 있습니다. 다만, 프로그램 코드와 이벤트를 처리하는 코드가 분리되어 있어 코드 관리나 리뷰가 번거로울 수 있으며 인자로 전달되는 이벤트 발생 View 객체 이외의 다른 위젯에 대한 접근이 어렵다는 문제가 있습니다.

MyBtnListener.java

public class MyBtnListener implements OnClickListener {
    public void onClick(View v) {
        // 이벤트 발생시 처리할 코드 구현
    }
}

MainActivity.java

Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new MyBtnListener());

만일 동일 액티비티에 포함된 위젯을 대상으로 하는 이벤트 리스너를 정의하는 경우 별도의 클래스를 만들지 않고 액티비티 클래스에서 리스너 인터페이스를 구현하는것이 유리할 수 있습니다.

public class MainActivity extends AppCompatActivity implements OnClickListener {
    ...
    public void onClick(View v) {
        // 이벤트 발생시 처리할 코드 구현
    }
}

익명의 이너 클래스로 구현

가장 많이 사용하는 방법으로 위젯별로 처리하는 내용이 상이 하거나 복잡하지 않은 구현에 유리합니다. 어차피 View 바인딩이 필요한 상황에서 이벤트 핸들러를 등록하는 코드가 추가되는 형태로 코드 관점에서 보면 관리와 이해가 제일 편한 구조 입니다. 또한 동일 Activity 클래스의 바인딩된 위젯들을 별도의 코드 추가 없이 사용할 수 있다는 점도 장점이라 할 수 있습니다. 그러나 이벤트 처리내용이 거의 동일하거나 재활용해야 하는 코드가 많은 경우 비슷한 코드가 중복 구현될 수 있어 이에 대한 보완이 필요합니다.

MainActivity.java

Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        // 이벤트 발생시 처리할 코드 구현
    }
})


이벤트 유형

View 에서 발생할 수 있는 이벤트의 종류는 다음과 같습니다. 해당 이벤트 처리를 위해서는 각각의 리스너 인터페이스를 구현하면서 콜백 메서드에 처리하고자 하는 내용을 작성해야 합니다. 기본 제공되는 이벤트 리스너 인터페이스는 하나의 콜백 메서드만을 제공하고 있습니다.

클릭(Click)

해당 뷰를 클릭시 발생하는 이벤트 입니다.

롱클릭(Long Click)

클릭후 바로 놓지 않고 계속 누르고 있는 롱클릭시 발생하는 이벤트 입니다.

포커스변화(Focus Change)

View 이동을 통해 포커스가 활성화 된 경우 발생하는 이벤트 입니다. 예를 들어 입력칸이 여러개 있을때 입력후 탭을 이용해 다음 칸으로 이동할때 새로운 입력칸에 포커스가 활성화 됩니다.

키 입력(Key Press/Release)

키를 누르거나 키에서 손을 떼면 호출되는 이벤트 입니다.

터치(Touch)

화면을 누르거나 손을 떼는 동작을 포함해 화면에서 이루어지는 모든 동작이 포함됩니다.

컨텍스트 메뉴(Context Menu)

롱클릭의 결과로 컨텍스트 메뉴가 구축중일때 호출 되는 이벤트 입니다. 컨텍스트 메뉴란 상황에 따라 동작하는 메뉴로 에를 들어 마우스 오른쪽 클릭과 같이 안드로이드에서 아이콘이나 이미지등을 길게 누르고 있을때 나타나는 메뉴등이 해당 됩니다.

이 외 특정 뷰 위젯들의 이벤트 리스너들은 참고 자료에서 확인하기 바랍니다.

커스텀 View 클래스를 구현하는 경우 기본 핸들러로 사용될 콜백 메서드를 하나이상 정의할 수 있습니다. 대표적으로 onKeyDown, onKeyUp, onTouchEvent, onFocusChanged 등이 있습니다. 예를들어 Activity 클래스의 경우 onTouchEvent() 메서드를 오버라이딩할 수 있으며 이경우 액티비티 전체에서 발생하는 이벤트를 처리할 수 있지만 개별 View 를 통해 이벤트를 처리하는 것이 보다 일반적입니다.

실습 및 참고자료

실습: 다양한 이벤트 유형 처리

Example2_1 에서 만든 코드를 프로그램 코드에서 리스너를 등록하는 방법으로 구현해 보고 onClick 이외의 여러 이벤트를 처리해 봅니다.

본 예제는 다음과 같은 내용들을 학습하기 위한 내용으로 구성 됩니다.

프로젝트 준비

실행 결과

따라하기 및 코드 설명

유튜브 동영상 강좌를 참고해 주세요


참고자료