GDSC HUFS 3기/Android with Kotlin Team 3

[3팀] 14-8 화면 구성하기: 커스텀 위젯

pacif1c0 2021. 11. 14. 22:23

이 글은 이것이 안드로이드다 with 코틀린(개정판)를 참고하여 작성하였습니다.

작성자 : 박진영

개발환경은 Windows, Android Studio입니다.

 

 

1. 커스텀 위젯

커스텀 위젯은 커스텀 뷰와 유사하게 화면을 구성하는 위젯을 직접 커스텀하는 방식이다. xml 파일에서 태그 형태로 xml에서 커스텀 위젯을 생성하려고 한다. attrs.xml이라는 곳에서 위젯의 속성을 정의하고, 위젯의 클래스를 정의해주면 된다.

res/values에 attrs.xml이라는 파일을 생성, 새로 만들 위젯에 대해서 정의해준다. 우리가 만들려고 하는 위젯은 숫자 text를 자동 인식하여 날짜 구분자를 삽입시키는 위젯이다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomText"> // 정의
        <attr name="delimeter" format="string" /> // attribute 생성
    </declare-styleable>
</resources>

그리고 새 위젯을 정의할 클래스를 생성한다. 부 생성자 세 개를 생성하는데, attrs는 태그로 이 위젯을 만들 때 속성들을 넘겨받는 부분이고, defStyleAttr은 같이 넘어올 수 있는 스타일을 의미한다. 이 중에서 두 번째 부생성자를 사용한다.

 

class CustomText : AppCompatTextView {
		// 부생성자 
    constructor(context:Context) : super(context) { } // 부생성자에서는 super 키워드를 활용하여 부모에게 값을 넘겨준다.
		constructor(context: Context, attrs:AttributeSet) : super(context, attrs) {
        // 전해져온 attrs 중 필요한 attr만 꺼내오는 작업, R.styleable.CustomText에 들어있는 것만.
        val attrlist = context.obtainStyledAttributes(attrs, R.styleable.CustomText)

        for(i in 0 until attrlist.indexCount) {
            val attr = attrlist.getIndex(i)
            when(attr){
                R.styleable.CustomText_delimeter -> {
                    attrlist.getString(attr)?.let{
                        process(it)
                    }
                }
            }
        }
    }
    constructor(context: Context, attrs:AttributeSet, defStyleAttr:Int) : super(context, attrs, defStyleAttr) { }
    
}

미리 생성한 res/value/attrs.xml에 있는 styleable 요소인 delimeter만 obtainStyledAttributes로 꺼내서 attrlist에 담는다. 그리고 반복무능ㄹ 활용해서 process 함수로 하나씩 꺼내 보내면, 아래와 같이 가공한다.

		fun process(delimeter:String){
        if(text.length == 8){
            val year = text.substring(0, 4)
            val month = text.substring(4, 6)
            val day = text.substring(6)

            text = year + delimeter + month + delimeter + day
        }
    }

가공 후에, activity_main.xml 파일 안에서 커스텀 위젯을 정의한다. 이는 똑같이 Design 페이지에서도 할 수 있다. 주목할만한 점은 우리가 선언해주었던 delimeter라는 attribute가 새로 생성된 것을 확인 가능하다는 점이다.

<com.example.customwidget.CustomText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="20211107"
    android:textSize="50sp"
    app:delimeter="-"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

날짜를 집어넣고 delimeter을 생성하면, 화면에 정상적으로 가공된 커스텀 텍스트를 확인할 수 있다.

결과화면