[Andorid] UMC Study - 5주차
ListView
https://velog.io/@sjlim/Andorid-UMC-Study-3%EC%A3%BC%EC%B0%A8
마지막 장 ListView 참조!
RecyclerView
-
화면안에 들어갈 한정된 수의 뷰를 유지함으로써 매우 효율적으로 스크롤 할 수 있음
-
리스트뷰와 다르게 재활용이 가능한 뷰
-
아래로 스크롤 할때마다 맨위에 존재하는 뷰객체를 아래쪽에 나타날 뷰 위치로 객체를 이동시키는 즉, 재사용하는 하는 동작 방식
-
이때 맨 처음 뷰객체를 기억하고 있을 뷰홀더가 필요하고 어댑터와 레이아웃매니저가 필요
1) LayoutManager
- 아이템 View의 크기 및 위치를 결정해 주는 역할 수행
ex) LinearLyaoutManager
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// context, 방향(가로/세로), reverse layout 여부
2) Adapter
- RecyclerView에 표시 될 View를 공급하는 클래스
- 3가지 메소드를 오버라이딩
onCreateViewHolder : ViewHolder 생성하여 반환
onBindViewHolder : ViewHoler에 값을 설정
getItemcount : 아이템의 개수 반환
3) ViewHolder
- RecyclerView.ViewHolder 클래스
- RecyclerView에 배치되는 View의 설정을 담당
- onCreateViewHolder에 의해 생성
4) 데이터 리스트 예제
- Album 데이터 클래스 생성 및 정보 관리
data class Album (
var title: String? = "",
var singer: String? = "",
var coverImg: Int? = null,
var songs: ArrayList<Song>? = null
)
- 더미데이터 생성
private var albumDatas = ArrayList<Album>();
albumDatas.apply {
add(Album("Butter", "방탄소년단 (BTS)", R.drawable.img_album_exp))
add(Album("Lilac", "아이유 (IU)", R.drawable.img_album_exp2))
add(Album("Next Level", "에스파 (AESPA)", R.drawable.img_album_exp5))
add(Album("Boy with Luv", "방탄소년단(BTS)", R.drawable.img_album_exp3))
add(Album("City", "오왼 (Owen)", R.drawable.img_album_exp6))
add(Album("고해", "오왼 (Owen)", R.drawable.img_album_exp4))
}
- 리사이클러뷰의 한 행을 채워줄 아이템 레이아웃 생성 (item_album.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<androidx.cardview.widget.CardView
android:id="@+id/item_album_cover_img_cv"
android:layout_width="150dp"
android:layout_height="150dp"
app:cardCornerRadius="7dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:id="@+id/item_album_cover_iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/img_album_exp2"
android:scaleType="fitCenter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.cardview.widget.CardView>
<ImageView
android:id="@+id/item_album_play_iv"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="5dp"
android:src="@drawable/widget_black_play"
app:layout_constraintBottom_toBottomOf="@id/item_album_cover_img_cv"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/item_album_title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LILAC"
android:textSize="20sp"
android:textColor="@color/black"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/item_album_cover_img_cv"/>
<TextView
android:id="@+id/item_album_singer_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="아이유 (IU)"
android:textSize="15sp"
android:layout_marginTop="3dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/item_album_title_tv"/>
</androidx.constraintlayout.widget.ConstraintLayout>
- Activity에서 RecyclerView의 LayoutManager 관리
binding.homeTodayAlbumRv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
- Adapter 생성
- 리사이클러뷰와 item을 한줄씩 맵핑시키고, 데이터를 넣어주는 역할을 함
- Adapter 클래스를 상속받아서 만듦
class AlbumRVAdapter(private val albumList: ArrayList<Album>) :
RecyclerView.Adapter<AlbumRVAdapter.ViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): AlbumRVAdapter.ViewHolder {
val binding: ItemAlbumBinding = ItemAlbumBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup,false)
return ViewHolder(binding)
}
// 아이템 뷰 홀더에 데이터 바인딩
override fun onBindViewHolder(holder: AlbumRVAdapter.ViewHolder, position: Int) {
holder.bind(albumList[position])
}
// data set 크기를 알려주는 함수 => 리사이클러뷰의 마지막이 어디인지 알 수 있음
override fun getItemCount(): Int = albumList.size
// ViewHolder, inner class로 생성
inner class ViewHolder(val binding: ItemAlbumBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(album : Album) {
binding.itemAlbumTitleTv.text = album.title
binding.itemAlbumSingerTv.text = album.singer
binding.itemAlbumCoverIv.setImageResource(album.coverImg!!)
}
}
}
- 어댑터 연결
// 어댑터 설정
val albumRVAdapter = AlbumRVAdapter(albumDatas)
// rv와 adapter 연결
binding.homeTodayAlbumRv.adapter = albumRVAdapter
5) RecyclerView에서의 Click Listener
- Adapter에서 인터페이스 정의
// step 1
interface MyItemClickListener{
fun onItemClick(album : Album)
fun onRemoveAlbum(position: Int)
}
// listener 객체 전달 받는 함수 & 저장하는 변수
private lateinit var mItemClickListener: LockerSaveRVAdapter.MyItemClickListener
fun setMyItemClickListener(itemClickListener: LockerSaveRVAdapter.MyItemClickListener){
mItemClickListener = itemClickListener
}
fun removeItem(position: Int) {
albumList.removeAt(position)
notifyDataSetChanged()
}
- ViewHolder를 통해 itemView에 접근 해 리스너 달기
// step 2
holder.itemView.setOnClickListener {
mItemClickListener.onItemClick(albumList[position])
}
holder.binding.itemSaveMoreIb.setOnClickListener {
mItemClickListener.onRemoveAlbum(position)
}
- Activity(Fragment)에서 adapter의 인터페이스 구현
// step 3
saveRVAdapter.setMyItemClickListener(object: LockerSaveRVAdapter.MyItemClickListener{
override fun onItemClick(album: Album) {
}
override fun onRemoveAlbum(position: Int) {
saveRVAdapter.removeItem(position)
}
})
more 버튼 클릭하면 data 삭제되게 구현!
Author And Source
이 문제에 관하여([Andorid] UMC Study - 5주차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sjlim/Andorid-UMC-Study-6주차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)