춤추는 개발자

[Android Studio] 기본 지식 배우기 - 3 본문

Android/study_til

[Android Studio] 기본 지식 배우기 - 3

Heon_9u 2020. 11. 27. 20:22
728x90
반응형

3. 이벤트 처리하기

3-1. View 클래스를 상속받아서 처리하기

package com.example.mywork00;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MyView myView = new MyView(this);
        setContentView(myView);
    }

    class MyView extends View {
        MyView(Context context) {
            super(context);
            setBackgroundColor(Color.GREEN);
        }

        public boolean onTouchEvent(MotionEvent event) {
            
            if(event.getAction() == MotionEvent.ACTION_DOWN) {
                Toast.makeText(MainActivity.this, "뷰 클래스를 상속받아 만든 이벤트 처리",
                        Toast.LENGTH_SHORT).show();
            }
            return false;
        }
    }
}

View 클래스는 안드로이드 기기에서 사용자와 기기가 상호작용하는데 큰 역할을 합니다. View 클래스는 이벤트(예: 터치, 드래그 등)가 발생하게 되면 자동으로 콜백 함수를 호출합니다. 예를 들어, 사용자가 화면을 터치할 경우, onTouchEvent 콜백 메소드가 자동으로 호출됩니다.

 

View 클래스가 가지고 있는 이벤트 처리 콜백 메소드
onKeyDown(int, keyEvent) Key이벤트가 발생했을 때, 호출
onKeyUp Key에서 손을 떼면 호출
onTrackballEvent(MotionEvent) trackball motion에 의해 호출
onTouchEvent(MotionEvent) touch screen motion에 의해 호출

 

View 클래스와 Activity 클래스는 onTouchEvent 콜백 메소드를 가지고 있는데, View 클래스의 메소드가 우선순위가 높다. 위 코드는 Toast 클래스를 이용해 화면에 잠시 동안 메시지를 띄운 것으로 결과 화면은 다음과 같다.

 

 

 

3-2. 리스너 인터페이스 구현하기

여기서 리스너는 '잘 듣고 있는'의 의미로 이벤트 발생 시, 콜백 메소드가 작동하게 된다. 콜백 메소드를 가지고 있는 인터페이스는 View 클래스 안에 정의되는데, 이러한 인터페이스를 리스너 인터페이스라고 한다. 인터페이스는 implements를 이용해서 구현한다.

 먼저, 이벤트 리스너를 구현하는 클래스를 만들고, 객체를 생성한다. 다음으로 위젯에 setOnClickListener 메소드를 이용해서 리스너 객체를 등록하면 된다.

 

package com.example.mywork00;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button b1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyListener myListener = new MyListener();

        b1 = (Button) findViewById(R.id.b1);
        b1.setOnClickListener(myListener);
    }

    class MyListener implements View.OnClickListener {
        public void onClick(View v) {
            Toast.makeText(MainActivity.this, "리스너 인터페이스를 구현하여 이벤트 처리",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <Button
        android:id="@+id/b1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button"/>

</LinearLayout>

setOnClickListener는 뷰(여기서는 xml에서 정의한 버튼)에 리스너 객체를 등록하는 역할을 한다. OnClickListener는 View 클래스 안에 인터페이스로 정의되어 있으며 아직 구현되지 않은 onClick메소드를 가지고 있다.

 

 

3-3. 무명 클래스로 처리하기

지금까지 콜백 메소드를 사용하기 위해서 구현(상속)을 받는 클래스를 만들고 객체를 생성해서 사용하였다. 하지만 이런 과정이 번거롭다면 무명 클래스를 통해 해결할 수 있다.

 

인터페이스 변수 = new 인터페이스() {
    // 실체 메소드
};   /// 실행문이므로 마지막에 세미클론을 적어야 한다.
b1.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {

    }
});

무명 클래스를 활용한 이벤트 처리는 클래스의 선언과 객체 생성을 동시에 하여 코드길이를 줄일 수 있다. 예시는 위와 같다.

 

package com.example.mywork00;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button b1, b2;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        b1 = (Button) findViewById(R.id.b1);
        b2 = (Button) findViewById(R.id.b2);
        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "ON", Toast.LENGTH_SHORT).show();
            }
        });

        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "Life goes on", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

이는 xml파일에서 id가 b1, b2인 버튼을 찾아서 버튼 변수를 연결해줬다. b1, b2에 무명 클래스를 사용해서 리스너 객체를 등록해줬다. 각각 버튼이 클릭이 되는 경우, 서로 다른 콜백 메소드 onClick(View v)이 실행된다.

이번에는 두 버튼을 하나의 리스너 객체로 표현하면 아래와 같다.

 

package com.example.mywork00;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

        Button.OnClickListener myClick = new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch(v.getId()) {
                    case R.id.b1:
                        Toast.makeText(getApplicationContext(), "ON", Toast.LENGTH_SHORT).show();
                        break;

                    case R.id.b2:
                        Toast.makeText(getApplicationContext(), "Life goes on", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        };
        
        findViewById(R.id.b1).setOnClickListener(myClick);
        findViewById(R.id.b2).setOnClickListener(myClick);
    }
}

 

OnClickListenerstatic interface이기 때문에 Button.OnClickListener로 바로 접근할 수 있고 static으로 선언된 것은 클래스명으로 직접 접근할 수 있다. Interface로부터 무명 클래스를 바로 선언하고 객체화시키는 방법이다. Interface는 바로 객체화할 수 없기 때문에 보통 class에서 implement를 한 후 사용한다. 만약 그 클래스를 재사용하지 않는 경우에는 무명 클래스를 활용하는 것이다.

 위 코드이 결과는 아래와 같다.

 

※ Toast 기능 살펴보기

  • 화면에 메시지를 잠깐 나타내는 클래스
  • makeText(): 토스트 객체를 생성
  • makeText(Context context, CharSequence text, int duration)
    • text: 메시지
    • duration: 지속시간
  • show(): 메시지를 표시한다. 마무리 메소드

3-4. onClick 속성 이용하는 방법

xml파일에서 Button 뷰의 onClick을 사용하는 방법이다. onClick 속성값에 이벤트를 처리하는 메소드 이름을 적는 방법은 쉽게 작성할 수 있다는 장점이 있다.

 먼저, Java에서 함수를 만든 후 이를 xml의 Button 뷰에서 호출하는 방식으로 사용한다.

 

package com.example.mywork00;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

    public void buttonListener1(View v) {
        Toast.makeText(getApplicationContext(), "ON", Toast.LENGTH_SHORT).show();
    }

    public void buttonListener2(View v) {
        Toast.makeText(getApplicationContext(), "Life gose on", Toast.LENGTH_SHORT).show();
    }
}

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <Button
        android:id="@+id/b1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="BTS: MAP OF THE SOUL 7"
        android:onClick="buttonListener1"/>

    <Button
        android:id="@+id/b2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="BTS: BE"
        android:onClick="buttonListener2"/>

</LinearLayout>

 

 

오늘은 이벤트처리하는 방법에 대해 배웠습니다. 다음 포스팅은 버튼을 활용해 간단한 앱 만들기에 도전해보겠습니다! 

728x90
반응형