Notice
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
Tags
- 큐 자바 코드
- 안드로이드 라이선스
- 서비스 쓰레드 차이
- 안드로이드 유닛테스트란
- 안드로이드 레트로핏 crud
- 안드로이드 라이선스 종류
- 안드로이드 레트로핏 사용법
- 2022 플러터 안드로이드 스튜디오
- jvm 작동 원리
- android retrofit login
- rxjava disposable
- android ar 개발
- Rxjava Observable
- ar vr 차이
- rxjava hot observable
- 플러터 설치 2022
- ANR이란
- 서비스 vs 쓰레드
- 안드로이드 유닛 테스트
- rxjava cold observable
- 스택 큐 차이
- 스택 자바 코드
- 객체
- 2022 플러터 설치
- 클래스
- 안드로이드 유닛 테스트 예시
- jvm이란
- 멤버변수
- 자바 다형성
- 안드로이드 os 구조
Archives
- Today
- Total
나만을 위한 블로그
[Manifest-Android] 39. 커스텀 뷰 구현 방법 본문
728x90
반응형
커스텀 뷰 클래스 생성
기본 뷰 클래스(View, ImageView, TextView 등)를 확장하는 새 클래스를 정의한다. 그 후 구현할 커스텀 동작에 따라 onDraw(), onMeasure(), onLayout() 같은 필요한 메서드, 생성자를 재정의한다.
아래는 onDraw()를 오버라이드하여 캔버스에 적접 빨간색 원을 그리는 커스텀 뷰다.
class CustomCircleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : View(context, attrs, defStyle) {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.RED
style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(width / 2f, height / 2f, min(width, height) / 4f, paint)
}
}
XML에서 커스텀 뷰 사용
커스텀 뷰 클래스를 생성한 후 XML 레이아웃 파일에서 직접 참조할 수 있다. 커스텀 클래스의 전체 패키지 경로를 정확하게 입력해야 한다. XML에서 정의할 수 있는 커스텀 속성(layout_width 등)을 커스텀 뷰에 전달할 수도 있다.
<com.example.myapp.ui.CustomCircleView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"/>
커스텀 속성 추가
values 폴더에 attrs.xml을 만들고 커스텀 속성을 정의할 수 있다. 이걸 통해 XML에서 뷰 속성을 커스텀할 수 있다.
위의 커스텀 뷰에서 원 색깔, 반지름을 커스텀할 수 있게 해서 재사용성을 확장할 수 있다.
<resources>
<declare-styleable name="CustomCircleView">
<attr name="circleColor" format="color"/>
<attr name="circleRadius" format="dimension"/>
</declare-styleable>
</resources>
커스텀 뷰 클래스에선 context.obtainStyledAttributes()를 써서 커스텀 속성 값을 가져올 수 있다.
class CustomCircleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
var circleColor: Int = Color.RED
var circleRadius: Float = 50f
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.FILL
}
init {
attrs?.let {
getAttrs(it, defStyleAttr)
}
paint.color = circleColor
}
private fun getAttrs(attrs: AttributeSet, defStyleAttr: Int) {
val typedArray = context.obtainStyledAttributes(
attrs, R.styleable.CustomCircleView, defStyleAttr, 0
)
try {
setTypeArray(typedArray)
} finally {
typedArray.recycle()
}
}
private fun setTypeArray(typedArray: TypedArray) {
circleColor = typedArray.getColor(R.styleable.CustomCircleView_circleColor, Color.RED)
circleRadius = typedArray.getDimension(R.styleable.CustomCircleView_circleRadius, 50f)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(width / 2f, height / 2f, circleRadius, paint)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredWidth = (circleRadius * 2 + paddingLeft + paddingRight).toInt()
val desiredHeight = (circleRadius * 2 + paddingTop + paddingBottom).toInt()
val width = resolveSize(desiredWidth, widthMeasureSpec)
val height = resolveSize(desiredHeight, heightMeasureSpec)
setMeasuredDimension(width, height)
}
fun setCircleProperties(color: Int, radius: Float) {
this.circleColor = color
this.circleRadius = radius
paint.color = color
requestLayout()
invalidate()
}
}
XML에선 아래처럼 커스텀 속성을 사용한다.
<com.example.myapp.ui.CustomCircleView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/customCircleView"
android:layout_width="100dp"
android:layout_height="100dp"
app:circleColor="@color/blue"
app:circleRadius="30dp"/>
반응형
'스터디' 카테고리의 다른 글
| [Manifest-Android] 40. 커스텀 뷰 생성자에서 @JvmOverloads 사용 시 주의점 (0) | 2025.07.29 |
|---|---|
| [Manifest-Android] 38. ViewStub (0) | 2025.07.29 |
| [Manifest-Android] 37. View, ViewGroup의 차이 (0) | 2025.07.29 |
| [Manifest-Android] 36. findViewTreeLifecycleOwner()의 역할 (0) | 2025.07.29 |
| [Manifest-Android] 35. View 생명주기 (0) | 2025.07.22 |
Comments