라떼는말이야

[Android] 버튼 상속해서 커스텀 버튼 만들기 (Bitmap Button) 본문

안드로이드

[Android] 버튼 상속해서 커스텀 버튼 만들기 (Bitmap Button)

MangBaam 2021. 3. 19. 20:07
반응형

자바 클래스 생성

BitmapButton

BitmapButton이라는 자바 클래스를 새로 생성해준다.

 

자바 클래스를 생성하면 public class BitmapButton { } 으로 생성이 되는데

버튼을 상속해서 커스텀 버튼을 만들 예정이니 버튼을 상속해줘야 한다.

AppCompatButton 을 상속하면 된다.

빨간 밑줄이 쳐있는데 생성자가 없기 때문이다.

 

마우스 우클릭 - [Generate...] - [Constructor]

 

매개변수가 하나짜리와 두개짜리가 있는 생성자를 선택해서 OK를 눌러준다.

 

하나짜리는 JAVA를 위한 생성자이고,

두개짜리는 XML을 위한 생성자라고 한다.

 

Ctrl 을 누르고 선택하면 중복 선택이 가능하다.

 

init 메소드 작성

init 메소드를 작성해준다. (이름이 꼭 init일 필요는 없다)

init 메소드의 역할은 커스텀 할 버튼의 배경(색상), 버튼에 들어가는 글자의 크기, 색 등을 지정하기 위함이다.

private void init(Context context) {
        setBackgroundResource(R.drawable.title_bitmap_button_normal);
        
        float textSize = getResources().getDimension(R.dimen.text_size);
        setTextSize(textSize);
        setTextColor(Color.WHITE);
}

 

res/drawable 폴더 밑에 미리 title_bitmap_button_clickedtitle_bitmap_button_normal 이미지를 넣어놨다.

setBackgroundResource 메소드로 버튼의 배경 이미지를 지정하는데 그 이미지를 R.drawable.이미지이름 으로 가져올 수 있다.

 

텍스트 사이즈를 지정하는 부분은 아래의 포스트 참고

2021.03.19 - [매일 공부 기록] - [Android] res/values에서 textSize 지정하기

 

[Android] res/values에서 textSize 지정하기

res/values 밑에 dimens.xml 파일을 생성한다. 16dp resources 태그 안에 dimen 태그를 넣고 이름과 크기를 지정한다. float textSize = getResources().getDimension(R...

latte-is-horse.tistory.com

이렇게 작성한 init 메소드를 myBitmapButton 클래스의 생성자에 넣어준다. 그 결과는 다음과 같다

 

터치 이벤트 추가

버튼의 모양까지 작성되었다.

버튼이 터치되었을때와 손에 떼어졌을때 이미지를 다르게 하여 버튼이 눌리는 효과를 주고자 한다.

 

Ctrl + o 를 눌러 onTouchEvent 메소드를 삽입해준다.

자동으로 생성되는 return super.onTouchEvent(event); 를 지우고 다음과 같이 입력해준다.

@Override
public boolean onTouchEvent(MotionEvent event) {
  int action = event.getAction();

  switch(action) {
    case MotionEvent.ACTION_DOWN:
      setBackgroundResource(R.drawable.title_bitmap_button_clicked);     
      break;
    case MotionEvent.ACTION_UP:
      setBackgroundResource(R.drawable.title_bitmap_button_normal);
      break;
  }

  invalidate();

  return true;
}

event.getAction()은 이벤트에 따른 값을 반환해주는데 그 반환 값은 MotionEvent.상수 로 구성된다.

버튼이 눌렸을때와 떼어졌을 때의 이벤트는 MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP 이 반환된다.

스위치 문으로 버튼이 눌리거나 떼어졌을 때 상황에 맞춰 이미지를 바꿔준다.

 

그리고 중요한 것이 invalidate() 메소드인데, invalidate가 있어야지 바뀐 이미지를 화면에 갱신해주기 때문에 필수적이다.

 

return true를 하면 이벤트가 계속적으로 받아들여진다.

 

전체코드

package com.example.button;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatButton;

public class BitmapButton extends AppCompatButton {
    public BitmapButton(@NonNull Context context) {
        super(context);

        init(context);
    }

    public BitmapButton(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        init(context);
    }

    private void init(Context context) {
        setBackgroundResource(R.drawable.title_bitmap_button_normal);

        float textSize = getResources().getDimension(R.dimen.text_size);
        setTextSize(textSize);

        setTextColor(Color.WHITE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();

        switch(action) {
            case MotionEvent.ACTION_DOWN:
                setBackgroundResource(R.drawable.title_bitmap_button_clicked);
                break;
            case MotionEvent.ACTION_UP:
                setBackgroundResource(R.drawable.title_bitmap_button_normal);
                break;

        }

        invalidate(); // 그래픽 다시 그림

        return true;
    }
}

 


위에서 버튼을 상속받아 새로운 버튼의 형태를 만들었다면 다음은 새로 만든 버튼을 사용해보는 과정이다.

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


    <com.example.button.BitmapButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

</LinearLayout>

위에서 만든 버튼 클래스 이름이 BitmapButton이었다.

activity_main.xml 파일에 커스텀 한 버튼을 추가할 때는 패키지 이름과 함께 사용하는데

어차피 자동완성 되기 때문에 외울 필요는 없다.

반응형
Comments