카드를 사용하여 이미지 목록 표시

1. 시작하기 전에

이전 Codelab에서는 RecyclerView에 텍스트 목록을 표시하는 Affirmations 앱을 만들었습니다.

7ac81c2a9a79365b.png

계속해서 이번 Codelab에서는 앱에 나오는 각각의 긍정적 문구에 감동적인 이미지를 추가합니다. Android 라이브러리 Material Component의 MaterialCardView 위젯을 사용하여 카드 내에서 긍정적 텍스트 및 이미지를 각각 표시합니다. 그런 다음, UI에 세련미를 입히고 더 일관되고 아름다운 사용자 환경을 만들어 앱을 완성합니다. 다음은 완성된 앱의 스크린샷입니다.

8d7a20a5d7a079ce.png

기본 요건

  • 앱에 이미지 리소스를 추가할 수 있음
  • XML 레이아웃을 쉽게 수정할 수 있음
  • RecyclerView에 텍스트 목록을 표시하는 앱을 만들 수 있음
  • RecyclerView의 어댑터를 만들 수 있음

학습할 내용

  • RecyclerView에 표시되는 긍정적 문구 목록에 이미지를 추가하는 방법
  • RecyclerView 항목 레이아웃에서 MaterialCardView를 사용하는 방법
  • 앱이 더 세련되게 보이도록 UI에서 시각적인 변화를 주는 방법

빌드할 프로그램

  • RecyclerView를 사용하여 카드 목록을 표시하는 개선된 Affirmations 앱입니다. 각 카드에는 이미지 및 긍정적인 텍스트가 포함됩니다.

필요한 항목

  • Android 스튜디오 버전 4.1 이상이 설치된 컴퓨터
  • 이미지 파일을 다운로드하기 위해 인터넷 연결에 액세스 가능
  • 이전 Affirmations 앱 만들기 Codelab의 Affirmations 앱 (시작 코드가 제공되지 않습니다. 앱 생성은 기본 요건입니다.)

2. 목록 항목에 이미지 추가

지금까지 RecyclerView에 긍정적인 문구의 문자열을 표시하는 어댑터인 ItemAdapter를 만들었습니다. 이 어댑터는 기능적으로는 훌륭하게 작동하지만 시각적으로 그다지 매력적이지 않습니다. 이 작업에서는 목록 항목 레이아웃 및 어댑터 코드를 수정하여 긍정적 문구와 함께 이미지를 표시합니다.

이미지 다운로드

  1. 시작하려면 Android 스튜디오에서 이전 Codelab의 Affirmations 앱 프로젝트를 엽니다. 이 프로젝트가 없다면 이전 Codelab의 단계를 진행하여 프로젝트를 만듭니다. 그런 다음, 다시 여기로 돌아옵니다.
  2. 다음으로, 컴퓨터에 이미지 파일을 다운로드합니다. 앱의 각 긍정적 문구마다 하나씩 10개의 이미지가 있어야 합니다. 파일 이름을 image1.jpg~image10.jpg로 지정해야 합니다.
  3. 컴퓨터의 이미지를 Android 스튜디오 내 프로젝트의 res > drawable 폴더(app/src/main/res/drawable)로 복사합니다. 이러한 리소스를 앱에 추가하면 R.drawable.image1과 같은 리소스 ID를 사용하여 코드에서 이러한 이미지에 액세스할 수 있습니다. (이미지를 찾으려면 Android 스튜디오의 코드를 다시 빌드해야 할 수도 있습니다.)

이제 앱에서 이미지를 사용할 준비가 되었습니다.

Affirmation 클래스에서 이미지 지원 추가

이 단계에서는 Affirmation 데이터 클래스에서 이미지 리소스 ID의 값을 보유하는 속성을 추가합니다. 이렇게 하면 단일 Affirmation 객체 인스턴스에 긍정적인 문구 텍스트의 리소스 ID 및 긍정적인 이미지의 리소스 ID가 포함됩니다.

  1. model 패키지 내의 Affirmation.kt 파일을 엽니다.
  2. imageResourceId라는 또 다른 Int 매개변수를 추가하여 Affirmation 클래스의 생성자를 수정합니다.

리소스 주석 사용

stringResourceIdimageResourceId는 모두 정숫값입니다. 문제가 없어 보이지만, 호출자가 실수로 잘못된 순서로 인수를 전달할 수 있습니다(stringResourceId 대신 imageResourceId 먼저).

이를 방지하기 위해 리소스 주석을 사용할 수 있습니다. 주석은 클래스, 메서드 또는 매개변수에 부가적인 정보를 추가하므로 유용합니다. 주석은 항상 @ 기호로 선언됩니다. 이 경우에는 @StringRes 주석을 문자열 리소스 ID 속성에 추가하고 @DrawableRes 주석을 드로어블 리소스 ID 속성에 추가합니다. 그러면 잘못된 유형의 리소스 ID를 제공하는 경우 경고가 표시됩니다.

  1. @StringRes 주석을 stringResourceId에 추가합니다.
  2. @DrawableRes 주석을 imageResourceId에 추가합니다.
  3. 패키지 선언 뒤 파일의 상단에 androidx.annotation.DrawableResandroidx.annotation.StringRes 가져오기를 추가했는지 확인합니다.

Affirmation.kt

package com.example.affirmations.model

import androidx.annotation.DrawableRes
import androidx.annotation.StringRes

data class Affirmation(
   @StringRes val stringResourceId: Int,
   @DrawableRes val imageResourceId: Int
)

이미지로 긍정적 문구 목록 초기화

Affirmation 클래스의 생성자를 변경했으므로 이제 Datasource 클래스를 업데이트해야 합니다. 초기화되는 각 Affirmation 객체에 이미지 리소스 ID를 전달합니다.

  1. Datasource.kt를 엽니다. Affirmation을 각각 인스턴스화하는 것에 관한 오류가 표시됩니다.
  2. Affirmation마다 이미지의 리소스 ID를 인수로 추가합니다(예: R.drawable.image1).

Datasource.kt

package com.example.affirmations.data

import com.example.affirmations.R
import com.example.affirmations.model.Affirmation

class Datasource() {

    fun loadAffirmations(): List<Affirmation> {
        return listOf<Affirmation>(
            Affirmation(R.string.affirmation1, R.drawable.image1),
            Affirmation(R.string.affirmation2, R.drawable.image2),
            Affirmation(R.string.affirmation3, R.drawable.image3),
            Affirmation(R.string.affirmation4, R.drawable.image4),
            Affirmation(R.string.affirmation5, R.drawable.image5),
            Affirmation(R.string.affirmation6, R.drawable.image6),
            Affirmation(R.string.affirmation7, R.drawable.image7),
            Affirmation(R.string.affirmation8, R.drawable.image8),
            Affirmation(R.string.affirmation9, R.drawable.image9),
            Affirmation(R.string.affirmation10, R.drawable.image10)
        )
    }
}

목록 항목 레이아웃에 ImageView 추가

목록에서 각 긍정적 문구의 이미지를 표시하려면 항목 레이아웃에 ImageView를 추가해야 합니다. 이제 2개의 뷰(TextViewImageView)가 있으므로 이러한 뷰를 ViewGroup 내의 하위 뷰로 배치해야 합니다. 뷰를 세로 열로 정렬하려면 LinearLayout을 사용하면 됩니다. LinearLayout은 모든 하위 뷰를 세로 또는 가로의 단일 방향으로 정렬합니다.

a5cb4349a970c992.png

  1. res > layout > list_item.xml을 엽니다. 기존 TextView 주위에 LinearLayout을 추가하고 orientation 속성을 vertical로 설정합니다.
  2. xmlns schema 선언 줄을 TextView 요소에서 LinearLayout 요소로 이동하여 오류를 제거합니다.

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
  1. LinearLayout, 내에서 TextView, 앞에 리소스 ID가 item_imageImageView를 추가합니다.
  2. ImageView의 너비를 match_parent로 높이를 194dp로 설정합니다. 화면 크기에 따라 이 값은 언제든지 화면에 몇 개의 카드를 표시합니다.
  3. scaleTypecenterCrop.으로 설정합니다.
  4. 이미지가 장식용으로 사용되므로 importantForAccessibility 속성을 no로 설정합니다.
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="194dp"
        android:id="@+id/item_image"
        android:importantForAccessibility="no"
        android:scaleType="centerCrop" />

ItemAdapter를 업데이트하여 이미지 설정

  1. adapter/ItemAdapter.kt를 엽니다(app > java > adapter > ItemAdapter).
  2. ItemViewHolder 클래스로 이동합니다.
  3. ItemViewHolder 인스턴스는 목록 항목 레이아웃에서 TextView에 대한 참조 및 ImageView에 대한 참조를 보유해야 합니다. 다음과 같이 변경합니다.

textView 속성의 초기화 아래에 imageView라는 val을 추가합니다. findViewById()를 사용하여 ID가 item_imageImageView에 대한 참조를 찾아 이를 imageView 속성에 할당합니다.

ItemAdapter.kt

class ItemViewHolder(private val view: View): RecyclerView.ViewHolder(view) {
    val textView: TextView = view.findViewById(R.id.item_title)
    val imageView: ImageView = view.findViewById(R.id.item_image)
}
  1. ItemAdapter에서 onBindViewHolder() 함수를 찾습니다.
  2. 이전에는 긍정적 문구의 stringResourceIdItemViewHoldertextView로 설정했습니다. 이제 긍정적 문구 항목의 imageResourceId를 목록 항목 뷰의 ImageView로 설정합니다.
    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        val item = dataset[position]
        holder.textView.text = context.resources.getString(item.stringResourceId)
        holder.imageView.setImageResource(item.imageResourceId)
    }
  1. 앱을 실행하고 긍정적 문구 목록을 스크롤합니다.

485d002900657409.png

앱이 이미지로 인해 훨씬 더 매력적으로 보입니다! 그렇지만 여전히 앱 UI 개선의 여지는 있습니다. 다음 섹션에서는 앱을 약간 조정하여 UI를 개선합니다.

3. UI 개선

지금까지 긍정적인 문구 문자열 및 이미지 목록으로 구성된 기능적인 앱을 빌드했습니다. 이 섹션에서는 코드 및 XML의 사소한 변경으로 앱이 더욱 세련되게 보이게 하는 방법을 알아보겠습니다.

패딩 추가

먼저, 목록의 항목 사이에 공백을 추가합니다.

  1. item_list.xml을 엽니다(app > res > layout > item_list.xml). 그리고 16dp 패딩을 기존 LinearLayout에 추가합니다.

list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">
  1. 16dp 패딩을 item_title TextView에 추가합니다.
  2. TextView에서 textAppearance 속성을 ?attr/textAppearanceHeadline6으로 설정합니다. textAppearance는 텍스트별 스타일을 정의할 수 있는 속성입니다. 그 외에 미리 정의된 텍스트 모양 값의 경우 이 일반적인 테마 속성에 관한 블로그 게시물의 TextAppearances 섹션을 참고하세요.
    <TextView
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:textAppearance="?attr/textAppearanceHeadline6" />
  1. 앱을 실행합니다. 이 목록이 더 좋아 보이나요?

a95304a44a8876d7.png

카드 사용

이미지가 위 또는 아래에 있는 긍정적 텍스트 중 어디에 속하는지 구별하기가 여전히 어렵습니다. Card 뷰를 사용하여 이 문제를 해결할 수 있습니다. Card 뷰를 사용하면 컨테이너의 스타일을 일관되게 유지하면서 간편하게 뷰 그룹을 포함할 수 있습니다. 카드 사용에 관한 자세한 Material Design 안내는 카드에 관한 이 가이드를 참고하세요.

  1. 기존 LinearLayout 주위에 MaterialCardView를 추가합니다.
  2. 다시 한번 스키마 선언을 LinearLayout에서 MaterialCardView로 이동합니다.
  3. MaterialCardViewlayout_widthmatch_parent로, layout_heightwrap_content로 설정합니다.
  4. 8dplayout_margin을 추가합니다.
  5. 공백이 너무 많지 않도록 LinearLayout에서 패딩을 삭제합니다.
  6. 이제 앱을 다시 실행합니다. MaterialCardView를 사용하여 각 긍정적 문구를 더 명확하게 구별할 수 있나요?

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/item_image"
            android:layout_width="match_parent"
            android:layout_height="194dp"
            android:importantForAccessibility="no"
            android:scaleType="centerCrop" />

        <TextView
            android:id="@+id/item_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:textAppearance="?attr/textAppearanceHeadline6" />

    </LinearLayout>

</com.google.android.material.card.MaterialCardView>

af61b5d2baa66e39.png

앱 테마 색상 변경

기본 앱 테마 색상은 선택 가능한 다른 몇 가지 옵션만큼 차분한 느낌을 주지 않을 수 있습니다. 이 작업에서는 앱 테마 색상을 파란색으로 변경합니다. 그런 다음, 자신의 아이디어를 활용하여 다시 변경할 수 있습니다!

링크의 Material Design 색상 팔레트에서 미리 정의된 파란색 셰이드를 찾을 수 있습니다.

이 Codelab에서는 다음과 같은 Material Design 팔레트의 색상을 사용합니다.

  • blue_200: #FF90CAF9
  • blue_500: #FF2196F3
  • blue_700: #FF1976D2

색상 리소스 추가

앱 내에서 사용되는 색상을 중앙 위치인 colors.xml 파일에 정의합니다.

  1. colors.xml을 엽니다(res > values > colors.xml).
  2. 정의된 파란색 색상에 관한 파일에 아래와 같이 새 색상 리소스를 추가합니다.
<color name="blue_200">#FF90CAF9</color>
<color name="blue_500">#FF2196F3</color>
<color name="blue_700">#FF1976D2</color>

테마 색상 변경

이제 새 색상 리소스가 있으므로 테마에서 사용할 수 있습니다.

  1. themes.xml을 엽니다(res > values > themes > themes.xml).
  2. <!-- Primary brand color. --> 섹션을 찾습니다.
  3. colorPrimary를 추가하거나 변경하여 @color/blue_500을 사용합니다.
  4. colorPrimaryVariant를 추가하거나 변경하여 @color/blue_700을 사용합니다.
<item name="colorPrimary">@color/blue_500</item>
<item name="colorPrimaryVariant">@color/blue_700</item>
  1. 앱을 실행합니다. 앱 바 색상이 파란색으로 변경된 것을 확인할 수 있습니다.

8d7a20a5d7a079ce.png

어두운 테마 색상 업데이트

앱의 어두운 테마에는 채도가 더 낮은 색상을 선택하는 것이 좋습니다.

  1. 어두운 테마 themes.xml 파일을 엽니다(themes > themes.xml (night)).
  2. 다음과 같이 colorPrimarycolorPrimaryVariant 테마 속성을 추가하거나 변경합니다.
<item name="colorPrimary">@color/blue_200</item>
<item name="colorPrimaryVariant">@color/blue_500</item>
  1. 앱을 실행합니다.
  2. 기기의 설정에서 어두운 테마를 사용 설정합니다.

  1. 앱이 어두운 테마로 전환됩니다. 아래 스크린샷과 같이 표시됩니다.

6564b21429206ebc.png

  1. 이 시점에서 colors.xml 파일에서 사용되지 않는 색상(예: 기본 앱 테마에서 사용된 자주색 색상 리소스)을 삭제할 수도 있습니다.

앱 아이콘 변경

마지막 단계로, 앱 아이콘을 업데이트합니다.

  1. 앱 아이콘 파일 ic_launcher_foreground.xmlic_launcher_background.xml을 다운로드합니다. 브라우저에서 파일을 다운로드하지 않고 표시하는 경우 파일 > 페이지를 다른 이름으로 저장을 선택하여 파일을 컴퓨터에 저장합니다.
  2. Android 스튜디오에서 drawable/ic_launcher_background.xmldrawable-v24/ic_launcher_foreground.xml 파일을 삭제합니다. 이 두 파일은 이전의 앱 아이콘 파일이기 때문입니다. Safe delete (with usage search) 체크박스를 선택 해제할 수 있습니다.
  3. 그런 다음, res > drawable 폴더를 마우스 오른쪽 버튼으로 클릭하고 New > Image Asset을 선택합니다.

51e40f30078ad631.png

  1. Configure Image Asset 창에서 Foreground layer가 선택되어 있는지 확인합니다.

8c437aa925887439.png

  1. 아래쪽에서 Path 라벨을 찾습니다.
  2. Path 텍스트 상자 내의 폴더 아이콘을 클릭합니다.
  3. 컴퓨터에 다운로드한 ic_launcher_foreground.xml 파일을 찾아서 엽니다.

ddac89ef587fba99.png

  1. Background Layer 탭으로 전환합니다.
  2. Path 텍스트 상자 내의 Browse 아이콘을 클릭합니다.
  3. 컴퓨터의 ic_launcher_background.xml 파일을 찾아서 엽니다. 다른 변경은 필요하지 않습니다.
  4. Next를 클릭합니다.

c0c1986d1887afdb.png

  1. Confirm Icon Path 대화상자에서 Finish를 클릭합니다. 기존 아이콘을 덮어써도 괜찮습니다.
  2. 권장사항에 따라 새 벡터 드로어블 ic_launcher_foreground.xmlic_launcher_background.xmldrawable-anydpi-v26이라는 새 리소스 디렉터리로 이동할 수 있습니다. 적응형 아이콘은 API 26에서 도입되었으므로 이러한 리소스는 API 26 이상을 실행하는 기기에서만 사용됩니다(어떤 dpi든 관계없음).
  3. drawable-v24 디렉터리에 아무것도 남아 있지 않다면 이 디렉터리를 삭제합니다.
  4. 앱을 실행하고 앱 검색 창에서 새로운 멋진 앱 아이콘을 확인합니다.

649133c325fa9b17.png

  1. 마지막 단계로, 코드가 더 깔끔하게 유지되고 스타일 가이드라인을 준수하도록 프로젝트에서 Kotlin 및 XML 파일의 형식을 다시 지정합니다.

축하합니다. 감동적인 Affirmations 앱을 만들었습니다.

Android 앱에서 데이터 목록을 표시하는 방법에 관한 이 지식을 사용하여 다음에 무엇을 빌드할 수 있을까요?

4. 솔루션 코드

Affirmations 앱의 솔루션 코드는 아래의 GitHub 저장소에 있습니다.

  1. 프로젝트에 제공된 GitHub 저장소 페이지로 이동합니다.
  2. 브랜치 이름이 Codelab에 지정된 브랜치 이름과 일치하는지 확인합니다. 예를 들어 다음 스크린샷에서 브랜치 이름은 main입니다.

1e4c0d2c081a8fd2.png

  1. 프로젝트의 GitHub 페이지에서 Code 버튼을 클릭하여 팝업을 엽니다.

1debcf330fd04c7b.png

  1. 팝업에서 Download ZIP 버튼을 클릭하여 컴퓨터에 프로젝트를 저장합니다. 다운로드가 완료될 때까지 기다립니다.
  2. 컴퓨터에서 파일을 찾습니다(예: Downloads 폴더).
  3. ZIP 파일을 더블클릭하여 압축을 해제합니다. 프로젝트 파일이 포함된 새 폴더가 만들어집니다.

Android 스튜디오에서 프로젝트 열기

  1. Android 스튜디오를 시작합니다.
  2. Welcome to Android Studio 창에서 Open을 클릭합니다.

d8e9dbdeafe9038a.png

참고: Android 스튜디오가 이미 열려 있는 경우 File > Open 메뉴 옵션을 대신 선택합니다.

8d1fda7396afe8e5.png

  1. 파일 브라우저에서 압축 해제된 프로젝트 폴더가 있는 위치로 이동합니다(예: Downloads 폴더).
  2. 프로젝트 폴더를 더블클릭합니다.
  3. Android 스튜디오가 프로젝트를 열 때까지 기다립니다.
  4. Run 버튼 8de56cba7583251f.png을 클릭하여 앱을 빌드하고 실행합니다. 예상대로 작동하는지 확인합니다.

5. 요약

  • RecyclerView에 추가 콘텐츠를 표시하려면 기본 데이터 모델 클래스와 데이터 소스를 수정합니다. 그런 다음, 목록 항목 레이아웃 및 어댑터를 업데이트하여 데이터를 뷰에 설정합니다.
  • 리소스 주석을 사용하여 올바른 유형의 리소스 ID가 클래스 생성자에 전달되도록 합니다.
  • Android 라이브러리의 Material 구성요소를 사용하여 더 간편하게 앱이 권장 Material Design 가이드라인을 준수하도록 합니다.
  • MaterialCardView를 사용하여 Material 카드에 콘텐츠를 표시합니다.
  • 색상 및 간격의 측면에서 앱을 시각적으로 조금만 수정하면 앱이 더욱 세련되고 일관되게 보이도록 할 수 있습니다.

6. 자세히 알아보기

7. 작업에 도전해보기

이 Codelab 시리즈에서는 RecyclerView와 함께 LinearLayoutManager를 사용하는 방법을 알아보았습니다. RecyclerView는 다양한 LayoutManager를 사용하여 데이터를 서로 다르게 배치할 수 있습니다.

  • RecyclerViewlayoutManager 속성을 GridLayoutManager로 변경합니다.
  • 열 개수를 3으로 변경합니다.
  • 어댑터 레이아웃을 변경하여 데이터를 그리드로 시각화합니다.