우선 전체 코드를 써 보자.
package com.example.flo.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.viewpager2.widget.ViewPager2
import com.example.flo.albumfrag.AlbumFragment
import com.example.flo.albumfrag.AlbumRVAdapter
import com.example.flo.home.BannerVPAdapter
import com.example.flo.R
import com.example.flo.databinding.FragmentHomeBinding
import com.example.flo.dataclasses.Album
import com.example.flo.dataclasses.Song
import com.example.flo.activities.MainActivity
import com.google.gson.Gson
class HomeFragment : Fragment() {
lateinit var binding: FragmentHomeBinding
private var albumDatas = ArrayList<Album>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false)
// binding.homeAlbumImgIv1.setOnClickListener {
// //앨범 프래그먼트로 데이터 전달
// val bundle = Bundle()
// bundle.putString("album", binding.lilac.text.toString())
// bundle.putString("singer", binding.iu.text.toString())
//
// val albumFragment = AlbumFragment()
// albumFragment.arguments = bundle
//
// //화면 전환
// (context as MainActivity).supportFragmentManager.beginTransaction()
// .replace(R.id.main_frm, albumFragment)
// .commitAllowingStateLoss()
// }
// 데이터 리스트 생성 더미 데이터
albumDatas.apply {
add(
Album(
title = "Butter",
singer = "방탄소년단 (BTS)",
coverImage = R.drawable.img_album_exp,
songs = arrayListOf(
Song("01", "Butter", "방탄소년단 (BTS)"),
Song("02", "Permission to Dance", "방탄소년단 (BTS)"),
Song("03", "Butter (Instrumental)", "방탄소년단 (BTS)"),
Song("04", "Permission to Dance (Instrumental)", "방탄소년단 (BTS)")
)
)
)
add(
Album(
title = "Lilac",
singer = "아이유 (IU)",
coverImage = R.drawable.img_album_exp2,
songs = arrayListOf(
Song("01", "라일락", "아이유 (IU)"),
Song("02", "Flu", "아이유 (IU)"),
Song("03", "Coin", "아이유 (IU)"),
Song("04", "봄 안녕 봄", "아이유 (IU)"),
Song("05", "Celebrity", "아이유 (IU)"),
Song("06", "돌림노래", "아이유 (IU)"),
Song("07", "빈 컵", "아이유 (IU)"),
Song("08", "아이와 나의 바다", "아이유 (IU)"),
Song("09", "어푸 (Ah puh )", "아이유 (IU)"),
Song("10", "에필로그", "아이유 (IU)")
)
)
)
add(
Album(
title = "Temp",
singer = "김시선 (UMC)",
coverImage = R.drawable.img_potcast_exp
)
)
add(
Album(
title = "Classic",
singer = "베토벤 (Beethoven)",
coverImage = R.drawable.img_first_album_default,
songs = arrayListOf(
Song("01", "월광 소나타", "베토벤 (Beethoven)"),
Song("02", "비창 소나타", "베토벤 (Beethoven)"),
Song("03", "운명 교향곡", "베토벤 (Beethoven)"),
Song("04", "영웅 교향곡", "베토벤 (Beethoven)"),
Song("05", "환희의 송가", "베토벤 (Beethoven)"),
Song("06", "황제 협주곡", "베토벤 (Beethoven)")
)
)
)
}
val albumRVAdapter = AlbumRVAdapter(albumDatas)
binding.homeTodayMusicAlbumRv.adapter = albumRVAdapter
binding.homeTodayMusicAlbumRv.layoutManager = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL, false
)
albumRVAdapter.setMyItemClickListener(object : AlbumRVAdapter.MyItemClickListener {
override fun onItemClick(album: Album) {
changeAlbumFragment(album)
}
// override fun onRemoveAlbum(position: Int) {
// albumRVAdapter.removeItem(position)
// }
})
//광고 배너들 연결
val bannerAdapter = BannerVPAdapter(this)
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp))
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp2))
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp))
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp2))
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp))
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp2))
binding.homeBannerVp.adapter = bannerAdapter
//광고 뷰 페이지가 좌우로 스크롤 될수 있도록 지정
binding.homeBannerVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
return binding.root
}
private fun changeAlbumFragment(album: Album) {
(context as MainActivity).supportFragmentManager.beginTransaction()
.replace(R.id.main_frm, AlbumFragment().apply {
arguments = Bundle().apply {
val gson = Gson()
val albumJson = gson.toJson(album) //앨범객체를 Json으로 변환
putString("album", albumJson)
}
})
.commitAllowingStateLoss()
}
}
차근차근 하나 씩 분석해 보자.
class HomeFragment : Fragment()
프래그먼트 클래스를 상속받는 HomeFragment 클래스를 정의. Fragment클래스는 라이프사이클 메서드와 뷰 관련 메서드, 데이터 상태 관리 메서드와 프래그먼트 관리 관련 메서드를 멤버로 가진다.
private var albumDatas = ArrayList<Album>()
Album은 따로 생성해놓은 데이터 클래스이다. Album객체를 원소로 가지는 ArrayList를 생성한다.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false)
//일단 생략
return binding.root
}
- onCreateView : 프래그먼트가 화면에 표시될 때 호출되는 메서드. 라이프사이클의 일종. 바인딩 객체의 최상위 뷰를 반환하도록 설정
- inflater: LayoutInflater - XML레이아웃 파일을 실제 View객체로 바꿔주는 도구
- savedInstanceState: Bundle? - 프래그먼트가 이전에 저장한 상태가 있다면 여기서 전달됨. 화면 회전이나 앱 재시작 시 복원할 때 사용됨
// 앨범 데이터 리스트 생성 더미 데이터
albumDatas.apply {
add(
Album(
title = "Butter",
singer = "방탄소년단 (BTS)",
coverImage = R.drawable.img_album_exp,
songs = arrayListOf(
Song("01", "Butter", "방탄소년단 (BTS)"),
Song("02", "Permission to Dance", "방탄소년단 (BTS)"),
Song("03", "Butter (Instrumental)", "방탄소년단 (BTS)"),
Song("04", "Permission to Dance (Instrumental)", "방탄소년단 (BTS)")
)
)
)
add(
Album(
title = "Lilac",
singer = "아이유 (IU)",
coverImage = R.drawable.img_album_exp2,
songs = arrayListOf(
Song("01", "라일락", "아이유 (IU)"),
Song("02", "Flu", "아이유 (IU)"),
Song("03", "Coin", "아이유 (IU)"),
Song("04", "봄 안녕 봄", "아이유 (IU)"),
Song("05", "Celebrity", "아이유 (IU)"),
Song("06", "돌림노래", "아이유 (IU)"),
Song("07", "빈 컵", "아이유 (IU)"),
Song("08", "아이와 나의 바다", "아이유 (IU)"),
Song("09", "어푸 (Ah puh )", "아이유 (IU)"),
Song("10", "에필로그", "아이유 (IU)")
)
)
)
add(
Album(
title = "Temp",
singer = "김시선 (UMC)",
coverImage = R.drawable.img_potcast_exp
)
)
add(
Album(
title = "Classic",
singer = "베토벤 (Beethoven)",
coverImage = R.drawable.img_first_album_default,
songs = arrayListOf(
Song("01", "월광 소나타", "베토벤 (Beethoven)"),
Song("02", "비창 소나타", "베토벤 (Beethoven)"),
Song("03", "운명 교향곡", "베토벤 (Beethoven)"),
Song("04", "영웅 교향곡", "베토벤 (Beethoven)"),
Song("05", "환희의 송가", "베토벤 (Beethoven)"),
Song("06", "황제 협주곡", "베토벤 (Beethoven)")
)
)
)
}
여기서 Album과 Song 데이터 클래스를 보고 가자.
package com.example.flo.dataclasses
data class Song(
val num : String? = "01",
val title: String = "",
val singer: String = "",
//val img: Int = R.drawable.img_album_exp2
)
data class Album(
var title: String? = "",
var singer: String? = "",
var coverImage: Int? = null,
// 수록곡 정보용 arraylist
var songs: ArrayList<Song>? = arrayListOf()
)
앨범 데이터클래스는 Song객체 배열을 멤버로 가진다. 저 코드는 아까 만들어놓은 albumDatas 리스트에 앨범 객체를 추가하는 코드이다.
- apply메서드 : Kotlin의 스코프 함수 중 하나로, 어떤 객체에 대해 여러 작업을 할 때 그 객체를 스코프 안에서 this로 설정하면서 초기화하거나 설정하는 함수. apply 블록 안에서는 this를 쓰지 않아도 자동으로 현재 객체를 가리키는 것으로 간주
- add메서드 : MutableList나 ArrayList같은 변경 가능한 리스트에 새로운 요소를 추가하는 메서드.
나머지 코드들은 뷰페이저2와 리사이클러뷰를 구현한 코드인데 다음 게시물들에서 알아보도록 하자.
'안드로이드 스터디' 카테고리의 다른 글
| RecyclerView를 써 보자! (0) | 2025.11.02 |
|---|---|
| 뷰페이저2를 만들어 보고 탭 레이아웃과 연동시켜보자! (0) | 2025.11.01 |
| 메인액티비티 코드 분석 (0) | 2025.11.01 |
| 코틀린 기본 문법 정리 - 익명클래스와 익명객체 (0) | 2025.11.01 |
| 코틀린 기본 문법 정리 - 상속, 인터페이스 (0) | 2025.11.01 |