본문 바로가기
개발(Development)/Android(안드로이드)

[안드로이드 코틀린] 커스텀 View 전용 속성 정의 및 사용 방법: attr.xml

by 카레유 2021. 8. 20.

커스텀 뷰의 기초 사용 방법은 아래 글 참고

[안드로이드 코틀린] View 출력 원리와 커스텀뷰 생성/사용 방법 기초

 

커스텀 뷰를 사용할 때,

커스텀 뷰를 위한 속성을 정의하여 사용해야할 때가 있다.

 

방법은  간단하다.

1.  attr.xml 파일에 커스텀 속성을 정의해두고,

2. 커스텀 뷰 클래스에서 attr.xml 파일에 정의한 속성을 참조하여 뷰에 적용하도록 설정하고,

3. 레이아웃 XML 파일에서 <커스텀뷰>를 등록하면서 attr.xml 에 정의한 속성을 사용하면 된다.


# 커스텀 속성 정의 방법

1. res > values 경로에 attrs.xml 파일을 생성

 

2. <declare-styleable> 태그 생성

- name 항목에는 커스텀뷰 클래스명을 입력해준다.

 

3. <attr> 태그 생성

- name에는 속성명, format에는 속성의 타입을 정의해준다.

- <attr> 태그 하나가 속성 하나라고 생각하면 된다.

 

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="CustomView">
        <attr name="myShapeColor" format="color" />
        <attr name="myTextColor" format="color" />
        <attr name="myTextString" format="string" />
        <attr name="myTextSize" format="string" />
        <attr name="myStrokeColor" format="color" />
        <attr name="myStrokeWidth" format="string" />
    </declare-styleable>

</resources>

# 커스텀 속성 참조 방법

1. 커스텀뷰 클래스 생성 / 생성자 정의

1) View 클래스를 상속 받는 클래스를 생성하고,

2) 생성자는 2개는 가급적 둘다 정의해 준다.

* 여기서는 2번째 생성자만 사용하지만, 1번도 정의해두면 나중에서 코드상에서 뷰를 직접 생성할 수 있다.

class CustomView: View {

    // 1. 코드에서 View 객체를 생성할 때 주로 호출하는 생성자
    constructor(context: Context?) : super(context)

    // 2. 레이아웃xml에 등록한 View가 안드로이드에 의해 Inflate될 때 호출되는 생성자
    // 매개변수 AttributeSet 객체를 통해 attr.xml 에 정의한 커스텀 속성을 사용할 수 있다.
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)

}



2. attr.xml 에 정의한 속성 참조하기

- context.obtainStyledAttributes() 메서드를 호출하면 attr.xml에 정의된 속성 정보들이 typedArray 객체로 반환된다.

- 속성의 format에 따라 typedArray 객체에서 getString(), getInt(), getColor() 등을 호출해주면 속성 값이 반환된다.

- 매개변수는 R.styleable.CustomView_myShapeColor 형식으로 넣어주면 된다.(아래 코드를 보면 이해된다)

class CustomView: View {

    // 커스텀 속성을 참조하기 위한 변수
    private var myShapeColor: Int? = null

    // 생성자1: 코드에서 View 객체를 생성할 때 주로 호출
    constructor(context: Context?) : super(context)

    // 생성자2: 레이아웃xml에 등록한 View가 안드로이드에 의해 Inflate될 때 호출
    // 매개변수 AttributeSet 객체를 통해 attr.xml 에 정의한 커스텀 속성을 사용할 수 있다.
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs){
    
        if(attrs != null && context != null){
        
            // attr.xml파일 declare-styleable이 CustomView로 정의된 attr(속성)을 typeArray객체로 받아온다.
            val typedArr = context.obtainStyledAttributes(attrs, R.styleable.CustomView)
            
            // format을 구분하여 속성값 참조
            myShapeColor = typedArr.getColor(R.styleable.CustomView_myShapeColor, Color.YELLOW)
           
        }
    }

}

* typedArr.getColor()의 두번째 매개변수는 디폴트값을 설정하는 것이다.

 

 

3. 뷰에 적용하기

- 참조한 속성값은 onDraw() 메서드 등에서 자유롭게 사용해주면 된다.

class CustomView: View {

    // 커스텀 속성을 참조하기 위한 변수
    private var myShapeColor: Int? = null

    // 생성자1: 코드에서 View 객체를 생성할 때 주로 호출
    constructor(context: Context?) : super(context)

    // 생성자2: 레이아웃xml에 등록한 View가 안드로이드에 의해 Inflate될 때 호출
    // 매개변수 AttributeSet 객체를 통해 attr.xml 에 정의한 커스텀 속성을 사용할 수 있다.
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs){
    
        if(attrs != null && context != null){
        
            // attr.xml파일 declare-styleable이 CustomView로 정의된 attr(속성)을 typeArray객체로 받아온다.
            val typedArr = context.obtainStyledAttributes(attrs, R.styleable.CustomView)
            
            // format을 구분하여 속성값 참조
            myShapeColor = typedArr.getColor(R.styleable.CustomView_myShapeColor, Color.YELLOW)
           
        }
    }
    
     override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        
        val paint = Paint()
        
        // attr.xml 에서 참조해온 속성값을 적용
        paint.color = shapeColor ?: Color.BLACK
        
        canvas?.drawCircle(110f, 110f, 100f, paint)

}

# 커스텀 속성 사용(레이아웃 XML)

1. 레이아웃 XML 파일에 네임스페이스를 추가하고 사용해주면 된다.

- 추가해야할 네임스페이스 : xmlns:app="http://schemas.android.com/apk/res-auto"

<?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=".CustomViewActivity">

    <!-- 커스텀뷰 태그 내부에서 네임스페이스:속성명 형태로 사용 -->
    <com.example.text.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:myShapeColor="#FF000000" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

댓글