Q. 어떻게 사용해?
A.
레이아웃
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_recycler_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginTop="70dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
홀더
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainPageActivity">
<ImageView
android:id="@+id/iv_item_title"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_round_square"
android:clipToOutline="true"
android:scaleType="centerCrop"
android:src="@drawable/img_fan"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="2"
android:text="제목"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/iv_item_like"
app:layout_constraintStart_toEndOf="@+id/iv_item_title"
app:layout_constraintTop_toTopOf="@+id/iv_item_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
액티비티
//최상단 입력
private val adapter = Adapter(list)//어떤 어댑터인지 구체적으로 이름짓기
//onCreate 호출
getAdapter()
//함수
private fun getAdapter() {
_binding.mainRecyclerView.adapter = adapter //리사이클러뷰와 어댑터연결
//매니저연결
_binding.mainRecyclerView.layoutManager = LinearLayoutManager(this)// 리니어
_binding.mainRecyclerView.layoutManager = GridLayoutManager(this,2)// 그리드
//그리드는 레이아웃에도 추가해줘야한다.
//리사이클러뷰 디바이더
val decoration = DividerItemDecoration(this,LinearLayoutManager.VERTICAL)
_binding.mainRecyclerView.addItemDecoration(decoration)
}
//main
val intent = Intent(this, DetailPageActivity::class.java)//클릭이벤트
adapter = Adapter(list, itemClickListener = { item, position ->
intent.putExtra("DATA", list[position])
intent.putExtra("POSITION", position)
startActivity(intent)
}, itemLongClickListener = { position ->//롱클릭이벤트
remove(adapter, position)
return@Adapter true
})
어댑터
class Adapter(
private val item: MutableList<ProductInfo>,
private val itemClickListener: (item: ProductInfo, position: Int) -> Unit,
private val itemLongClickListener: (position: Int) -> Boolean
) : RecyclerView.Adapter<Adapter.Holder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Adapter.Holder {
val binding =
ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(binding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.bind(item[position])
}
override fun getItemCount(): Int {
return item.size
}
inner class Holder(private val binding: ItemRecyclerviewBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: ProductInfo) {
binding.apply {
ivItemTitle.setImageResource(item.image)
tvItemTitle.text = item.title
//클릭이벤트
itemRecyclerview.setOnClickListener {
itemClickListener(item, adapterPosition)
}
//롱클릭이벤트
itemRecyclerview.setOnLongClickListener {
itemLongClickListener(adapterPosition)
}
}
}
}
}
롱클릭이벤트 : 삭제
private fun removeItem(adapter: Adapter, position: Int) {
val builder = AlertDialog.Builder(this@MainPageActivity)
builder.setTitle(getString(R.string.eco_market))
builder.setMessage(getString(R.string.ask_remove))
builder.setIcon(R.drawable.ic_logo_eco)
val btnListener = DialogInterface.OnClickListener { dialog, which ->
if (which == DialogInterface.BUTTON_POSITIVE) {
adapter.notifyItemRemoved(position)
productList.removeAt(position)
adapter.notifyItemRangeChanged(position, adapter.itemCount)
}
}
builder.setPositiveButton(getString(R.string.yes), btnListener)
builder.setNegativeButton(getString(R.string.no), btnListener)
builder.show()
}
}
인터페이스로 만드는 방법
class Adapter(private val item: MutableList<ProductInfo>) : RecyclerView.Adapter<Adapter.Holder>() {
//로그용
companion object {
private const val TAG = "Adapter" }
//클릭이벤트용
interface ItemClick {
fun onClick(view : View, position : Int)
}
//클릭이벤트용
var itemClick : ItemClick? = null
//★필수사항 : 홀더생성
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Adapter.Holder {
val binding =
ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(binding)
}
//★필수사항 : 홀더바인딩
override fun onBindViewHolder(holder: Holder, position: Int) {
//클릭이벤트용
holder.itemView.setOnClickListener {
itemClick?.onClick(it, position)
}
//1000단위
val dec = DecimalFormat("#,###원")
//홀더 내 뷰 연결
holder.image.setImageResource(item[position].image)
}
//★필수사항
override fun getItemCount(): Int {
return item.size
}
//★필수사항 : 리사이클뷰연결
inner class Holder(private val binding: ItemRecyclerviewBinding) :
RecyclerView.ViewHolder(binding.root) {
val image = binding.ivItemTitle
}
}
리스트어댑터, 멀티뷰타입
Fragment 사용시 초기화, 옵저버 onViewCreated가 아닌 onCreateView에서 해야 submitList 적용가능
//타입 설정
const val LOADING = 0
const val ITEM = 1
class HomeRecyclerViewAdapter(
private val itemClickListener: (item: ContentModel) -> Unit
) : ListAdapter<ContentModel, ViewHolder>(diffUtil) {//뷰홀터로 지정, 객체 인자로 넘기기
//diffUtil 객체생성
companion object {
val diffUtil = object : DiffUtil.ItemCallback<ContentModel>() {
override fun areItemsTheSame(oldItem: ContentModel, newItem: ContentModel): Boolean {
return oldItem.uId == newItem.uId
}
override fun areContentsTheSame(oldItem: ContentModel, newItem: ContentModel): Boolean {
return oldItem == newItem
}
}
}
//타입 지정 함수
override fun getItemViewType(position: Int): Int {
return when(getItem(position)) {
is ContentModel -> ITEM//타입 지정조건 설정
else -> LOADING
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return if(viewType == ITEM) {
val binding =
RecyclerviewHomeHolderBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false)
ItemHolder(binding, itemClickListener)
}
else {val binding =
RecyclerviewHomeHolderLoadingBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
LoadingHolder(binding)
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if(holder is ItemHolder)
holder.bind(getItem(position))
}
class ItemHolder(
private val binding: RecyclerviewHomeHolderBinding,
private val itemClickListener: (ContentModel) -> Unit
) :
ViewHolder(binding.root) {
fun bind(item: ContentModel) {
binding.apply {
homeHolderTvTitle.text = item.title
homeHolderTvDateTime.text = Util.makeDateTimeFormat(item.dateTime)
binding.homeHolderIvSelected.isVisible = item.selectedContent
binding.homeHolderIvVideo.isVisible = item.type != "image"
homeHolder.setOnClickListener {
itemClickListener(item)
}
}
Glide.with(itemView.context)
.load(item.thumbnail)
.into(binding.homeHolderIvTitle)
}
}
}
class LoadingHolder(
private val binding: RecyclerviewHomeHolderLoadingBinding
) :
ViewHolder(binding.root) {
fun bind(item: ContentModel) {
binding.apply {
}
}
}
'나만의 AI > 안드로이드 도와줘' 카테고리의 다른 글
Android kotlin [Glide 알려줘] (0) | 2024.08.01 |
---|---|
Android kotlin [parcelize 알려줘] (0) | 2024.07.16 |
Android kotlin [Listener 알려줘] (0) | 2024.07.03 |
Android kotlin [intent 알려줘] (0) | 2024.07.02 |
Android kotlin [Binding 알려줘] (0) | 2024.07.01 |