라떼는말이야
[Android] 버튼 상속해서 커스텀 버튼 만들기 (Bitmap Button) 본문
자바 클래스 생성
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_clicked와 title_bitmap_button_normal 이미지를 넣어놨다.
setBackgroundResource 메소드로 버튼의 배경 이미지를 지정하는데 그 이미지를 R.drawable.이미지이름 으로 가져올 수 있다.
텍스트 사이즈를 지정하는 부분은 아래의 포스트 참고
2021.03.19 - [매일 공부 기록] - [Android] res/values에서 textSize 지정하기
이렇게 작성한 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 파일에 커스텀 한 버튼을 추가할 때는 패키지 이름과 함께 사용하는데
어차피 자동완성 되기 때문에 외울 필요는 없다.
'안드로이드' 카테고리의 다른 글
[Android] 현재 고민 중인 문제 : 화면 갱신 문제 (해결) (0) | 2021.05.28 |
---|---|
[Android] 뒤로 가기 두번 눌러 종료 구현 (0) | 2021.05.28 |
[Android] 로그인 구현하기 - 디자인 (0) | 2021.05.21 |
[Android] 영화 앱 기능 확장 (좋아요, 한줄평) (0) | 2021.03.25 |
[Android] res/values에서 textSize 지정하기 (0) | 2021.03.19 |
[Android] 터치 이벤트 처리 (0) | 2021.03.19 |
[Android] 첫 번째 프로젝트 : 네이버 영화 앱 만들기 (0) | 2021.03.18 |
[Android] 상태 드로어블 state drawable (0) | 2021.03.17 |