본문 바로가기
Projects/PlayStoreGameView

[Android/Kotlin] XML 속성으로 조정 가능한 GameListView 커스텀 뷰 구현과 활용 방법

by quessr 2024. 10. 2.

 

안드로이드에서 사용자 맞춤형 UI를 구현할 때 커스텀 뷰를 사용하는 것이 매우 유용합니다.
이번 포스팅에서는 GameListView라는 커스텀 뷰를 만들어, XML에서 속성만으로 쉽게 조정할 수 있는 방법을 소개합니다. 이 뷰는 게임 목록을 RecyclerView로 보여주며, 카드 유형과 레이아웃을 속성에 따라 유연하게 조정할 수 있습니다.

 

1. 커스텀 뷰 만들기

GameListView라는 커스텀 뷰는 LinearLayout을 확장하여 구현했습니다.
이 뷰는 게임 데이터를 리스트 형식으로 보여주며, RecyclerView를 통해 레이아웃을 구성합니다. 특히, 이 커스텀 뷰는 XML에서 속성을 정의하여 다양한 레이아웃을 설정할 수 있습니다. 즉, 뷰를 XML에 선언만 하면, 해당 속성을 이용해 간편하게 사용할 수 있습니다.

 

class GameListView @JvmOverloads constructor(
    context: Context,
    attr: AttributeSet? = null,
    @AttrRes defStyleAttr: Int = 0
) : LinearLayout(context, attr, defStyleAttr) {
    // View 속성 및 설정 코드...
}

주요 구현

  • GameListView는 LinearLayout을 상속받으며, RecyclerView를 통해 데이터를 리스트 형식으로 보여줍니다.
  • attrs.xml에서 속성을 받아와 레이아웃 옵션을 설정합니다. 카드의 유형에 따라 GridLayoutManager 또는 LinearLayoutManager를 적용할 수 있습니다.
  • submitList 함수는 외부에서 데이터를 전달받아 RecyclerView의 어댑터에 설정합니다.

2. attrs.xml에 속성 정의하기

GameListView에서 사용할 수 있는 다양한 속성들은 attrs.xml에 정의되어 있습니다. 이 속성을 통해 레이아웃을 더욱 유연하게 구성할 수 있습니다.

attrs.xml 설명

attrs.xml은 커스텀 뷰의 속성을 정의하는 파일입니다. 커스텀 뷰를 구현할 때 attrs.xml에 속성을 정의하면 XML 레이아웃 파일에서 뷰의 동작과 외형을 쉽게 제어할 수 있습니다. 이번 GameListView의 경우, 카드 유형, 이미지 크기, 타이틀 표시 여부 등 다양한 옵션을 제공하기 위해 속성을 정의했습니다.

<resources>
    <declare-styleable name="GameListView">
        <!-- 카드의 타입을 정의하는 속성 -->
        <attr name="cardType" format="enum">
            <enum name="big_promo_image" value="0" /> <!-- 큰 프로모 이미지 -->
            <enum name="list" value="1" />           <!-- 리스트 카드 -->
            <enum name="small_image" value="2" />     <!-- 작은 이미지 카드 -->
            <enum name="big_featured_image" value="3" /><!-- 큰 이미지 카드 -->
        </attr>

        <!-- 리스트 카드에서 사용할 spanCount (열 개수)를 정의하는 속성 -->
        <attr name="spanCount" format="integer" />

        <!-- 이미지 크기를 정의하는 속성 -->
        <attr name="imageViewSize" format="enum">
            <enum name="small" value="1" />  <!-- 작은 이미지 크기 -->
            <enum name="big" value="2" />    <!-- 큰 이미지 크기 -->
        </attr>

        <!-- 카테고리 타이틀의 가시성을 정의하는 속성 -->
        <attr name="categoryTitleVisibility" format="enum">
            <enum name="visible" value="1" /> <!-- 타이틀 표시 -->
            <enum name="gone" value="2" />    <!-- 타이틀 숨김 -->
        </attr>
    </declare-styleable>
</resources>

 

주요 속성 설명

  • cardType: 이 속성은 보여줄 카드의 유형을 정의합니다. 예를 들어, big_promo_image는 큰 프로모션 이미지를 보여주고, list는 리스트 형태의 카드를 나타냅니다.
  • spanCount: GridLayoutManager를 사용할 때 열의 개수를 정의하는 속성입니다. 기본적으로 리스트 카드는 여러 열로 구성될 수 있으며, 이 속성으로 열의 개수를 설정할 수 있습니다.
  • imageViewSize: 카드에 보여줄 이미지의 크기를 정의하는 속성입니다. 작은 이미지와 큰 이미지 두 가지 옵션을 제공하며, 이를 통해 다양한 카드 레이아웃을 만들 수 있습니다.
  • categoryTitleVisibility: 타이틀의 가시성을 설정하는 속성입니다. 타이틀을 표시할지, 숨길지를 설정할 수 있어 더 유연한 레이아웃 구성이 가능합니다.

속성 적용 방식: obtainStyledAttributes

이제 이 속성들이 어떻게 커스텀 뷰에서 인식되어 적용되는지 설명하겠습니다. 커스텀 뷰는 obtainStyledAttributes() 메서드를 사용하여 XML에서 정의된 속성을 가져옵니다.

context.theme.obtainStyledAttributes(attr, R.styleable.GameListView, 0, 0).apply {
    try {
        // XML에서 cardType 속성 값을 가져와 적용
        cardType = getInt(R.styleable.GameListView_cardType, 0)
        spanCount = getInt(R.styleable.GameListView_spanCount, 3)
        sizeType = getInt(R.styleable.GameListView_imageViewSize, ImageSizeConstants.SIZE_SMALL)
        titleVisibility = getInt(R.styleable.GameListView_categoryTitleVisibility, View.GONE)
    } finally {
        recycle() // 메모리 관리를 위해 recycle() 호출
    }
}

obtainStyledAttributes 설명:

  • obtainStyledAttributes()는 XML에서 정의된 속성을 TypedArray 객체로 가져옵니다.
  • 이 메서드를 통해 XML에서 정의한 속성 값을 커스텀 뷰에서 읽어올 수 있으며, 필요한 속성 값을 추출한 후 recycle()을 호출하여 메모리를 해제합니다.
  • getInt()와 같은 메서드로 속성 값을 읽어오며, 속성 값이 없을 경우 기본값을 설정할 수 있습니다.

이를 통해 attrs.xml에 정의된 속성들이 커스텀 뷰의 동작과 레이아웃에 영향을 미치게 됩니다.

3. 레이아웃 파일에서 사용하기

아래 코드는 리스트 형태의 카드 유형을 적용한 예시입니다.

<com.quessr.playstore_gameview.GameListView
    android:id="@+id/listChartGameListView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="30dp"
    app:cardType="list"
    app:categoryTitleVisibility="visible"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/title"
    app:spanCount="3" />

4. 마무리

GameListView는 LinearLayout을 기반으로 한 커스텀 뷰로, XML에서 다양한 속성을 통해 레이아웃을 쉽게 설정할 수 있습니다. 이러한 속성들은 obtainStyledAttributes 메서드를 통해 읽어와 적용되며, 이를 통해 뷰의 동작과 외형을 유연하게 조정할 수 있습니다.

반응형