Development record of developer who study hard everyday.

, , ,

안드로이드 커스텀뷰 만들기 예제

 안드로이드 커스텀뷰 만들기 예제


안드로이드 개발 블로그

22년 1월부터 안드로이드 개발자로 일을 시작했다.

지금 회사에 안드로이드 개발자가 1명 뿐인데 전임자가 5년차 개발자였다.

입사하자마자 5년차 개발자가 만든 소스를 수정하기시작했는데 내 실력에 너무 벅차다는 느낌을 많이 받았다.

라이브러리 같은 것은 공식 문서가 있으니까 공부하면 되는데 커스텀뷰를 사용한 부분은 도저히 이해가 가질 않았다.

그래서 이참에 구글링을 열심히해서 제대로 커스텀뷰를 파헤쳐보려고한다.

일단, 나는 커스텀뷰에 대해서 아무것도 모르기때문에 무작정 쉬운 예제를 따라해보았다.

참고한 글은 아래와 같다.

https://coding-idiot.tistory.com/8

너무 깔끔하게 정리되어있어서 따라하기도 쉽고 커스텀뷰의 개념을 이해하는데 도움이 되었다.

그럼 시작하자!

1. CustomView의 xml 만들기

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">

<TextView
android:id="@+id/tv_emoji_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="36sp"
android:text=""/>

<TextView
android:id="@+id/tv_title_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="추워요"
android:layout_marginBottom="4dp"
android:textStyle="bold"/>

<TextView
android:id="@+id/tv_count_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"/>

</LinearLayout>

</layout>

특별한건 없다.

텍스트뷰 3개가 연속되어있는 형태이다.


2. 커스텀뷰의 속성 정의

res/values 폴더에 attrs.xml 파일을 만들어준다.

그리고 커스텀뷰의 속성을 정의해준다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="EmojiButton">    
<attr name="emoji" format="string|reference"/>
<attr name="title" format="string|reference"/>
<attr name="count" format="integer"/>
</declare-styleable>
</resources>

declare-styleable의 name에 커스텀뷰의 이름을 적어준다.

그 아래 속성의 이름(name)과 타입(format)을 적어준다.

단, 주의해야할 사항이 있다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="EmojiButton">
    <attr name="emoji" format="string|reference"/>
    <attr name="title" format="string|reference"/>
    <attr name="count" format="integer"/>
    </declare-styleable>

    <declare-styleable name="TextButton">
    <attr name="title" format="string|reference"/>
    </declare-styleable>
</resources>

위 처럼 커스텀뷰를 여러개 만들 경우 속성의 이름과 포맷이 일치할 경우, 오류가 생긴다.

<resources>
<declare-styleable name="EmojiButton">
<attr name="emoji" format="string|reference"/>
<attr name="title" format="string|reference"/>
<attr name="count" format="integer"/>
</declare-styleable>

<declare-styleable name="TextButton">
<attr name="title"/>
</declare-styleable>
</resources>

이처럼 이미 선언된 속성은 다시 선언하지말고 그냥 이름만 가져다 쓰면 된다.


3. 뷰 클래스 구현

class EmojiButton(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {
private lateinit var binding : EmojibuttonLayoutBinding

init {
binding = EmojibuttonLayoutBinding.inflate(LayoutInflater.from(context), this, true)    //1

//attrs.xml에서 View의 속성 목록을 가져온다.
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.EmojiButton)    //2

val emoji = typedArray.getString(R.styleable.EmojiButton_emoji)
binding.tvEmojiButton.text = emoji

val title = typedArray.getString(R.styleable.EmojiButton_title)
binding.tvTitleButton.text = title

val count = typedArray.getInt(R.styleable.EmojiButton_count, 0)
binding.tvCountButton.text = count.toString()

typedArray.recycle()    //3
}
}

1-> 데이터바인딩 inflate 시에 attachToRoot를 true로 해준다. 그래야 커스텀뷰가 작동한다.

2-> attrs.xml에서 정의한 View의 속성 목록을 가져온다.

3-> 데이터를 캐싱해뒤어 가비지 컬렉션에서 제외시키도록 하는 함수

      typedArray 사용 후 호출해야하나, 커스텀뷰가 반복 사용되는 것이 아니라면 호출하지          않아도 무방

참고로 이미지를 받는 속성이라면 아래와 같이 불러올 수 있다.

val iconImageResource = typedArray.getResourceId(R.styleable.IconButton_icon, R.drawable.ic_drop)
binding.ivIcon.setImageResource(iconImageResource)


4. 커스텀뷰 사용하기

이제, 액티비티나 프래그먼트의 xml파일에서 커스텀뷰를 사용하자

<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">

<com.boo.sample.samplecustomview.EmojiButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:emoji=""
app:title="추워요"
app:count="0"/>

<com.boo.sample.samplecustomview.EmojiButton
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
app:emoji="🌬"
app:title="쌀쌀해요"
app:count="0"/>

<com.boo.sample.samplecustomview.EmojiButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:emoji="😀"
app:title="적당해요"
app:count="0"/>

<com.boo.sample.samplecustomview.EmojiButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:emoji="☀️"
app:title="따뜻해요"
app:count="0"/>

<com.boo.sample.samplecustomview.EmojiButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:emoji="🔥"
app:title="더워요"
app:count="0"/>

</LinearLayout>


이상이다.


원글을 작성해주신 개발자분이 너무 감사해서 댓글까지 남겼다. ㅋ

https://coding-idiot.tistory.com/8

다시 한 번 참고자료 남기고 감사의 인사를 올린다.


Share:
Location: 대한민국 서울특별시

댓글 없음:

댓글 쓰기