티스토리 뷰
안드로이드 API에서 제공하는 위젯을 사용하면 거의 대부분의 화면을 만들 수 있다. 하지만, 우리가 원하는 기능만 가진 커스텀 위젯을 따로 구상하여 새로운 뷰를 정의하는 것 또한 가능하다.
API에서 제공하는 뷰를 사용하려면 API의 뷰를 상속해야 한다. 이 때 뷰의 영역과 크기는 해당 뷰를 포함하고 있는 레이아웃의 영향을 받아 정해지며, 개발자가 뷰의 상태에 따라 추가적인 코드를 넣을 수 있도록 콜백 메서드가 호출된다.
뷰가 스스로의 크기를 정할 때 자동으로 호출되는 메서드는 onMeasure()이고 스스로를 레이아웃에 맞게 그릴 때는 onDraw() 가 호출된다.
일반적으로 사용하는 뷰 객체의 콜백 메서드는 다음과 같다.
- public void onMeasure(int widthMeasureSpec, int heightMeasureSpec): params는 해당 뷰 객체에 허용되는 폭과 높이이다.
- public void onDraw(Canvas canvas)
- void setMeasuredDimension(int measuredWidth, int measuredHeight): params는 해당 뷰 객체의 폭과 높이
- void invalidate(): 해당 뷰객체 삭제
바로 한번 예제와 함께 확인해보자.
우선 MyButton 이라는 새 클래스를 생성하고 일반적인 버튼의 동작을 하도록 AppCompatButton 클래스를 상속시켜준다.
◎MyButton.java
package com.example.sampleview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatButton;
public class MyButton extends AppCompatButton {
public MyButton(@NonNull Context context) {
super(context);
init(context);
}
public MyButton(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Log.d("MyButton", "onDraw 호출됨");
}
private void init(Context context) {
setBackgroundColor(Color.CYAN);
setTextColor(Color.BLACK);
float textSize = getResources().getDimension(R.dimen.text_size);
setTextSize(textSize);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("MyButton", "onTouch 호출됨");
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
setBackgroundColor(Color.BLUE);
setTextColor(Color.RED);
break;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
setBackgroundColor(Color.CYAN);
setTextColor(Color.BLACK);
break;
}
invalidate();
return true;
}
}
MyButton은 2개의 생성자 메서드를 가지고 있는데, 하나는 View객체를 포함할 액티비티의 컨텍스트를 가지고 다른 하나는 컨텍스트와 AttributeSet을 가지는 데 이는 XML 레이아웃에서 태그에 추가하는 속성을 전달받기 위한 것으로 반드시 필요하다.
또한 init() 메서드를 작성하면서 사용한 res/dimen.xml파일은 크기가 값 등을 정의할 수 있는 파일이다.
이제 생성한 뷰 객체를 레이아웃에 추가해보자.
◎activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.sampleview.MyButton android:layout_height="80dp" android:layout_width="200dp"
android:id="@+id/button" android:text="시작하기"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintBottom_toBottomOf="parent">
</com.example.sampleview.MyButton>
</androidx.constraintlayout.widget.ConstraintLayout>
반응형
'Mobile > Android' 카테고리의 다른 글
[Android] 선택 위젯 3: Recycler View (0) | 2022.04.03 |
---|---|
[Android] 선택 위젯 2: CardView (0) | 2022.04.02 |
[Android] 위험 권한 (0) | 2022.03.31 |
[Android] 브로드캐스트 수신자 이해하기 (0) | 2022.03.30 |
[Android] Service 1: Service 이해하기 (0) | 2022.03.29 |
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
- react-native
- redux
- redux-thunk
- Promise
- 맛집
- 정보보안기사 #실기 #정리
- 인천 구월동 이탈리안 맛집
- AsyncStorage
- Async
- javascript
- 이탈리안 레스토랑
- 인천 구월동 맛집
- react
- 파니노구스토
- await
- Total
- Today
- Yesterday