[TAVE 스터디 4주차] 음악 목록 앱 만들기

2026. 1. 4. 12:39·TAVE-16th

Section 06


🎧 RecyclerView

ListView vs. RecyclerView

기능 ListView RecyclerView
ViewHolder 패턴 선택 (성능 위해 권장) 필수 (구조적으로 강제)
레이아웃 구조 수직 스크롤만 가능 LayoutManager로 자유롭게 변경 (수직, 수평, 그리드 등)
아이템 애니메이션 기본 미지원 (구현 복잡) ItemAnimator로 간단하게 기본 애니메이션 적용 및 커스텀 가능
유연성 및 확장성 낮음 높음
구현 복잡도 상대적으로 간단 초기 설정이 조금 더 복잡함

기능 구현 순서

  1. 아이템 레이아웃 만들기: 리스트에 들어갈 아이템 화면(rv_item.xml)을 먼저 만든다.
  2. RecyclerView 배치하기: 아이템들을 담을 전체 틀인 RecyclerView를 activity_main.xml에 배치한다.
  3. 어댑터 생성하기: 데이터와 아이템 뷰를 연결할 RVAdapter.kt를 생성한다.
  4. Activity에서 모두 연결하기: MainActivity에서 데이터, 어댑터, LayoutManager를 RecyclerView에 최종적으로 설정한다.




🎧 Navigation & Fragment

네이게이션이란?

  • Jetpack 라이브러리의 일부로 애플리케이션 내에서 화면 전환을 처리를 담당하는 기능
  • 클릭 이벤트가 있거나 뒤로 가기 버튼이 눌렸을 때 다른 화면(Fragment)로 이동

[주요 구성요소]

  • NavHostFragment: 네비게이션 그래프의 목적지(Fragment)를 표시하는 컨테이너
  • Navigation Graph: XML 파일로 애플리케이션의 네비게이션 구조를 정의, 시작 화면에서 도착 화면이 어디인지 등등
  • NavHost: Navigation Graph에서 대상을 표시하는 빈 컨테이너, 화면 전환 때 사용
  • NavController: NavHost에서 대상 콘텐츠의 전환을 조종
  • Composables: 각각의 화면을 나타내는 함수

Navigation Graph에서 특정 경로를 따라 이동할지, 특정 대상으로 직접 이동할지 NavController에게 전달하고 NavController가 NavHost에 적절한 대상을 표시해주는 방식


Fragment

[개념]

  • 하나의 액티비티 안에 포함된 작은 화면 단위(UI 조각)
  • 독립적인 Lifecycle과 입력 이벤트 처리 가능
  • 액티비티 실행 중에도 프레그먼트를 추가하거나 삭제가 가능

즉, 여러개의 액티비티를 생성하여 전환하는 것이 아니라 프래그먼트를 만들어서 네비게이션의 클릭 이벤트가 발생할 때마다 프래그먼트를 전환하는 것임.

[장점]

  • 모듈성 - 화면을 독립된 조각으로 나눠서 관리
  • 유연성 - 화면 크기에 따라 다른 레이아웃 구성 가능
  • 재사용성
  • 백 스택 관리 - 한 화면에서 다른 화면으로 이동하면, 새로운 화면이 스택에 추가(Push) 되고, 뒤로 가기(Back)를 하면 스택에서 제거(Pop) 됨




🎧 Fragment 만들기

1. 네비게이션 생성하기

  • app -> New -> Android Resource File
  • Resource Type을 navigation으로 하고 파일 이름 입력 (e.g. main_nav)

2. 환경 설정

  • fragment를 사용하려면 Fragment 라이브러리가 프로젝트에 포함되야 함
  • 저절로 되긴 하지만 직접 추가할 수도 있음

(1) Google 저장소 추가 - setting.gradle

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        ...
    }
}

Android Studio가 google() 저장소를 참조하지 않으면 해당 라이브러리를 가져올 수 없기 때문

(2) Fragment 라이브러리 추가 - build.gradle

dependencies {
    val fragment_version = "1.8.9"

    // Java language implementation
    implementation("androidx.fragment:fragment:$fragment_version")
    // Kotlin
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
}

클래스 정의 파일이 프로젝트에 존재해야 하기 때문에 import를 위한 설정임

3. 프래그먼트 추가

*(1) 원하는 만큼 프래그먼트 추가하기 *

  • 경로: kotlin -> com.example -> New -> Fragment -> Fragment (Blank)
  • 이렇게 하면 Fragment 클래스(Singer1Fragment.kt), Fragment 레이아웃(fragment_singer1.xml) 가 생성됨

*(2) Navigation Graph에 Fragment 등록하기 *

  • 상단의 “New Destination (+)” 버튼 클릭
  • 생성한 Fragment 목록 중에서 원하는 것 선택하여 추가
  • 네비게이션 그래프에 새로운 도착지가 등록됨

*(2) Fragment 간 이동 경로(화살표) 연결하기 *

  • 네비게이션 그래프 창에서 시작할 Fragment를 클릭 -> 드래그하여 다른 Fragment로 화살표 연결
  • 코드로 보면 다음과 같이 추가가 됨
      <fragment
          android:id="@+id/singer1Fragment"
          android:name="com.example.week04_rc.Singer1Fragment"
          android:label="fragment_singer1"
          tools:layout="@layout/fragment_singer1" >
          <action
              android:id="@+id/action_singer1Fragment_to_singer2Fragment"
              app:destination="@id/singer2Fragment" />
          <action
              android:id="@+id/action_singer1Fragment_to_singer3Fragment"
              app:destination="@id/singer3Fragment" />
      </fragment>




🎧 음악 목록 앱 만들기 - 코드 실습

프래그먼트 모두 연결된 사진

RVAdapter.kt

1. class 선언

class RVAdapter(val items: MutableList<String>): RecyclerView.Adapter<RVAdapter.ViewHolder>() 
  • 파리미터는 MutableList
  • ViewHolder를 상속받아야 동작

2. onCreateViewHolder

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RVAdapter.ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.rv_item, parent, false)   
        // LayoutInflater → XML 레이아웃을 실제 View 객체로 변환.

        return ViewHolder(view)
    }
  • rv_item.xml 레이아웃을 화면에 붙이는(View 생성) 함수
  • RecyclerView는 스크롤 시 아이템을 계속 재활용하므로, 새로운 View가 필요할 때만 이 메서드가 호출됨

3. ViewHolder(itemView: View)

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bindItems(item: String){
            val rv_text = itemView.findViewById<TextView>(R.id.rvTextId)
            rv_text.text = item
        }
    }
  • 하나의 아이템 View를 관리하는 클래스
  • RecyclerView는 아이템이 많기 때문에 ViewHolder가 각 아이템의 View를 재활용해 메모리를 절약

Singer1Fragment.kt

Singer2Fragment.kt, Singer3Fragment.kt 도 있음

1. Fragment 기본 구조

class Singer1Fragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) { ... }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { ... }
}

2. 데이터 준비

val items = mutableListOf<String>()
items.add("Dynamite")
items.add("Butter")
  • 수정 가능한 리스트인 MutableList를 만들어서 음악 제목 데이터를 추가해주기

3. RecyclerView 세팅

val rv = view.findViewById<RecyclerView>(R.id.singRV)
val rvAdapter = RVAdapter(items)
rv.adapter = rvAdapter
rv.layoutManager = LinearLayoutManager(context) // 세로 스크롤 배치 방식 
  • xml 레이아웃에 있는 RecyclerView 연결
  • 아까 만든 어댑터 클래스 연결 -> items라는 이름의 MutableList를 넘겨줌 -> 화면에 표시

*4. 다른 Fragment로 이동 *

view.findViewById<ImageView>(R.id.blackpink).setOnClickListener {
    it.findNavController().navigate(R.id.action_singer1Fragment_to_singer2Fragment)
}

view.findViewById<ImageView>(R.id.aespa).setOnClickListener {
    it.findNavController().navigate(R.id.action_singer1Fragment_to_singer3Fragment)
}
  • 이미지를 클릭했을 때 실행되는 동작 지정
  • 네이게이션 컨트롤러를 가져와서 이동경로(action)대로 화면 전환

fragment_singer1.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Singer1Fragment">

    <TextView
        android:layout_width="match_parent"
        android:fontFamily="@font/hsfont"
        android:layout_height="60dp"
        android:background="#966AE7"
        android:gravity="center"
        android:text="BTS 노래 리스트"
        android:textColor="@color/white"
        android:textSize="30sp"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/singRV"
        android:layout_marginTop="70dp"
        android:layout_marginBottom="110dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        app:layout_constraintBottom_toBottomOf="parent">

        <ImageView
            android:id="@+id/bts"
            android:src="@drawable/bts"
            android:layout_margin="5dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:layout_weight="1" />

        <ImageView
            android:id="@+id/blackpink"
            android:src="@drawable/blackpink"
            android:layout_margin="5dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:layout_weight="1" />

        <ImageView
            android:id="@+id/aespa"
            android:src="@drawable/aespa"
            android:layout_margin="5dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:layout_weight="1" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>



🎧 실행결과

깃허브: 👾Github



'TAVE-16th' 카테고리의 다른 글

[DIP/FE] 프로젝트 소개 & Kakao Oauth 구현  (0) 2026.02.23
[TAVE 스터디 5주차] 메모 앱 만들기  (0) 2026.01.04
[TAVE 스터디 4주차] ListView 만들기 & 더블클릭 종료  (0) 2026.01.04
[TAVE 스터디 3주차] 주사위 앱 만들기  (1) 2026.01.04
[TAVE 스터디 2주차] 사진앱 만들기(2)  (0) 2026.01.04
'TAVE-16th' 카테고리의 다른 글
  • [DIP/FE] 프로젝트 소개 & Kakao Oauth 구현
  • [TAVE 스터디 5주차] 메모 앱 만들기
  • [TAVE 스터디 4주차] ListView 만들기 & 더블클릭 종료
  • [TAVE 스터디 3주차] 주사위 앱 만들기
choisio2
choisio2
sio2-dev 님의 블로그 입니다.
  • choisio2
    SiO2 for Developer
    choisio2
  • 전체
    오늘
    어제
    • 분류 전체보기 (46) N
      • TAVE-16th (14)
      • BDA-11th (16)
      • C++ (5)
      • 개인 프로젝트 (4)
      • 백준 (4) N
      • 컴퓨터 그래픽스 (1)
      • 잡담 (1)
  • 블로그 메뉴

    • 태그
    • 방명록
  • 링크

    • github.com/choisio2
  • 공지사항

  • 인기 글

  • 태그

    geminicli
    AI시대
    spotify
    kotlin
    kotin
    playconsole
    polling
    바이브코딩
    androidstudio
    frontend
    SpotifyAPI
    KakaoOauth
    개발자미래
    알고리즘스터디
    알고리즘
    viewpager2
    데시벨측정
    코딩테스트
    코테
    BDA #데이터분석모델링
    데이터분석모델링
    백준1463
    프론트엔드
    calculator
    개발자
    Tave
    BDA
    C++
    백준
    BDAI
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
choisio2
[TAVE 스터디 4주차] 음악 목록 앱 만들기
상단으로

티스토리툴바