개발일지

Android in A..Z - View (AttributeSet) 본문

Android (안드로이드)/View

Android in A..Z - View (AttributeSet)

강태종 2021. 4. 29. 15:11

AttributeSet

Android는 XML에서 View를 생성할 때 값을 설정할 수 있는 AttributeSet 인터페이스를 제공합니다. AttributeSet을 통해 View를 생성하면서 기본값을 쉽게 설정할 수 있습니다.


View 만들기

View를 상속받고 기본 생성자를 설정한다.

class ProgressView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : View(context, attrs, defStyleAttr, defStyleRes) {

}

AttributeSet 만들기

attr.xml에 선언하여 만들 수 있다. reference는 Resource에 있는 값을 사용할 수 있게 도와준다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="textColor" format="reference|color" />

    <declare-styleable name="ProgressView">
        <attr name="maxValue" format="reference|integer" />
        <attr name="value" format="reference|integer" />
        <attr name="textSize" format="reference|dimension" />
        <attr name="textColor" />
        <attr name="progressBarBackgroundColor" format="reference|color" />
        <attr name="progressBarColor" format="reference|color" />
        <attr name="progressBarWidth" format="reference|dimension" />
    </declare-styleable>

</resources>

값 설정하기

app namespace를 사용하여 AttributeSet에 정의한 값들을 설정할 수 있다.

            <com.taetae98.customview.view.ProgressView
                android:id="@+id/progress"
                app:progressBarColor="@color/purple_500"
                app:progressBarWidth="40dp"
                app:textSize="30sp"
                android:layout_margin="10dp"
                android:layout_gravity="center"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                tools:value="10"/>

 


값 추출하기

생성자에서 obtainStyledAttributes함수를 통해 넘겨받은 AttributeSet에서 값을 추출할 수 있다.

package com.taetae98.customview.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.os.Parcelable
import android.util.AttributeSet
import android.util.Log
import android.view.View
import com.taetae98.customview.R
import kotlin.math.min

class ProgressView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : View(context, attrs, defStyleAttr, defStyleRes) {
    private val progressBarBackgroundPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.STROKE
        color = Color.parseColor("#646F88")
        strokeWidth = 20 * resources.displayMetrics.density
    }
    private val progressBarPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.STROKE
        color = Color.parseColor("#61AFEF")
        strokeWidth = 20 * resources.displayMetrics.density
    }

    private val percentPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL_AND_STROKE
        textAlign = Paint.Align.CENTER
        textSize = 20 * resources.displayMetrics.density
        color = Color.parseColor("#000000")
    }

    var maxValue = 100
        set(value) {
            field = value
            invalidate()
        }

    var value = 0
        set(value) {
            field = value
            invalidate()
        }

    var textSize: Float
        get() {
            return percentPaint.textSize
        }

        set(value) {
            percentPaint.textSize = value
            invalidate()
        }

    var textColor: Int
        get() {
            return percentPaint.color
        }
        set(value) {
            percentPaint.color = value
            invalidate()
        }

    var progressBarBackgroundColor: Int
        get() {
            return progressBarBackgroundPaint.color
        }
        set(value) {
            progressBarBackgroundPaint.color = value
            invalidate()
        }

    var progressBarColor: Int
        get() {
            return progressBarPaint.color
        }
        set(value) {
            progressBarPaint.color = value
            invalidate()
        }

    var progressBarWidth: Float
        get() {
            return progressBarPaint.strokeWidth
        }
        set(value) {
            progressBarPaint.strokeWidth = value
            progressBarBackgroundPaint.strokeWidth = value
        }

    init {
        context.theme.obtainStyledAttributes(attrs, R.styleable.ProgressView, defStyleAttr, defStyleRes).apply {
            maxValue = getInt(R.styleable.ProgressView_maxValue, maxValue)
            value = getInt(R.styleable.ProgressView_value, value)
            textSize = getDimension(R.styleable.ProgressView_textSize, textSize)
            textColor = getColor(R.styleable.ProgressView_textColor, textColor)
            progressBarBackgroundColor = getColor(R.styleable.ProgressView_progressBarBackgroundColor, progressBarBackgroundColor)
            progressBarColor = getColor(R.styleable.ProgressView_progressBarColor, progressBarColor)
            progressBarWidth = getDimension(R.styleable.ProgressView_progressBarWidth, progressBarWidth)
        }
    }
}

Git (예제코드)

github.com/KangTaeJong98/Example/tree/main/Android/CustomView

 

KangTaeJong98/Example

My Example Code. Contribute to KangTaeJong98/Example development by creating an account on GitHub.

github.com

 

Comments