안드로이드에서 커스텀 뷰를 만들기 위해서는 보통 아래의 작업 과정을 거친다.
1) View 를 상속 받는 커스텀 뷰 클래스를 만들고,
2) onDraw() 메서드를 오버라이드해서 Canvas 객체로 그림를 그린다.
3) 레이아웃 XML파일에 커스텀 뷰를 추가한다.
예를 들어 아래와 같이 커스텀 뷰 클래스를 작성하고 띄워보자.
<커스텀뷰 클래스 코드>
class CustomViewSize: View {
// 생성자
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
// onDraw() 오버라이드: 그림 그리기
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
// 배경을 초록색으로 채우기
canvas?.drawColor(Color.GREEN)
// 파란색 원 그리기
val paint = Paint()
paint.color = Color.BLUE
canvas?.drawCircle(500f, 500f, 200f, paint)
}
}
<레이아웃 XML 코드>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".CustomViewSizeActivity">
<com.example.test.CustomViewSize
android:id="@+id/customViewSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<실행 결과>
레이아웃 XML파일에서 뷰의 width, height 를 wrap_content 로 설정했지만,
뷰의 전체 영역의 크기는 onDraw()에서 그린 원의 크기보다 크게 출력되었다!
안드로이드는 wrap_content 를 보는 순간,
뷰가 자체적으로 본인의 영역을 어느정도 크기로 출력할지 스스로 정한다고 간주한다.
(onDraw()에서 그린 그림의 크기를 알아서 인식해서 뷰의 크기를 결정해주지 않는다!)
따라서 커스텀뷰 클래스 내부에서
뷰 자체의 영역이 어느정도 크기가 될지 개발자가 따로 설정해 주어야 한다.
# 뷰 크기 설정 방법
View 클래스는 onDraw()메서드 뿐만 아니라,
onMeasure() 메서드를 통해 뷰의 영역 크기를 설정할 수 있는 방법을 제공한다.
onMeausre()메서드는 onDraw()가 호출되기 전에 호출되며,
내부에서 setMeasuredDimension(가로, 세로) 메서드를 호출해주면 뷰의 크기를 원하는대로 세팅해줄 수 있다.
*** onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) 메서드 사용방법
- 매개변수로 들어오는 widthMeasureSpec(가로), heightMeasureSpec(세로) 에는 레이아웃 XML에서 설정한 뷰의 크기 정보가 담겨 있다.
- 이를 통해 뷰의 크기와 모드를 확인하는 상세 방법은 아래와 같다.
1. 뷰의 크기 값 확인 방법
- 가로: MeasureSpec.getSize(widthMeasureSpec)
- 세로: MeasureSpec.getSize(heightMeasureSpec)
2. 뷰의 크기 모드 확인 방법
- MeasureSpec.getMode(widthMeasureSpec) 등으로 아래의 3가지 종류의 크기 모드를 확인할 수 있다.
1) MeasureSpec.AT_MOST: wrap_content -> 뷰 내부에서 자체적으로 뷰의 크기를 결정하라는 의미다.
2) MeasureSpec.EXACTLY: 특정 숫자값, match_parent, fill_parent 등 -> XML에서 설정된 값으로 뷰의 크기가 설정 된다.
3) MeasureSpec.UNSPECIFIED: 설정된 값 없음
뷰의 모드와 뷰의 크기를 확인한 다음,
상황에 맞게 setMeasuredDimension(가로, 세로) 메서드를 호출하여 뷰의 크기를 설정해주면 된다.
코드로 보면 다음과 같다.
class CustomViewSize: View {
// 생성자
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
// onMeasure() 메서드 오버라이드
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
// 뷰 크기 모드 체크
val viewWidthMode = MeasureSpec.getMode(widthMeasureSpec)
val viewHeightMode = MeasureSpec.getMode(heightMeasureSpec)
// 뷰 크기 값 체크
val viewWidthSize = MeasureSpec.getSize(widthMeasureSpec)
val viewHeightSize = MeasureSpec.getSize(heightMeasureSpec)
// 크기 모드에 따라 setMeasuredDimension() 메서드로 뷰의 영역 크기를 설정한다.
if(viewWidthMode == MeasureSpec.EXACTLY && viewHeightMode == MeasureSpec.EXACTLY){
// XML에서 뷰의 크기가 특정 값으로 설정된 경우, 그대로 사용한다.
setMeasuredDimension(viewWidthSize, viewHeightSize)
}else{
// wrap_content이거나, 지정되지 않은 경우, 뷰의 크기를 내부에서 지정해주어야 한다
setMeasuredDimension(1000, 1000)
}
}
// onDraw()메서드 오버라이드
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
// 배경을 초록색으로 채우기
canvas?.drawColor(Color.GREEN)
// 파란색 원 그리기
val paint = Paint()
paint.color = Color.BLUE
canvas?.drawCircle(500f, 500f, 200f, paint)
}
}
<실행결과>
설정한대로 뷰의 크기가 지정되어 출력된다.
'개발(Development) > Android(안드로이드)' 카테고리의 다른 글
[안드로이드] 여러개의 Fragment Swipe 구현 방법: ViewPager2 (0) | 2021.08.22 |
---|---|
[안드로이드 스튜디오] 다국어 지원 strings.xml 파일 생성 방법 (0) | 2021.08.22 |
[안드로이드] 원형 프로그레스바 동적으로 조정하는 방법 (0) | 2021.08.21 |
[안드로이드] 원형 프로그레스바 테두리 끝 둥글게 Roound 처리 방법 (0) | 2021.08.21 |
[안드로이드] 커스텀 원형 프로그레스 바(도넛 그래프) 만드는 방법 (0) | 2021.08.21 |
댓글