250x250
Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 주택가 잠실새내
- 막내의막무가내 SQL
- 막내의막무가내
- 부스트코스에이스
- Fragment
- 부스트코스
- 막내의막무가내 코볼 COBOL
- 프래그먼트
- 프로그래머스 알고리즘
- 주엽역 생활맥주
- 막내의막무가내 안드로이드 에러 해결
- 막무가내
- 막내의막무가내 플러터
- 막내의 막무가내
- 막내의막무가내 코틀린
- 막내의 막무가내 알고리즘
- 막내의막무가내 rxjava
- 막내의막무가내 플러터 flutter
- 막내의막무가내 안드로이드 코틀린
- flutter network call
- 막내의막무가내 안드로이드
- 안드로이드 Sunflower 스터디
- 막내의막무가내 프로그래밍
- 2022년 6월 일상
- 막내의막무가내 목표 및 회고
- 안드로이드 sunflower
- 안드로이드
- 막내의막무가내 코틀린 안드로이드
- 막내의막무가내 일상
- 막내의막무가내 알고리즘
Archives
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] 안드로이드 이중 어댑터(이중 리사이클러뷰) 구현 메모 (feat. 데이터바인딩) 본문
안드로이드/코틀린 & 아키텍처 & Recent
[안드로이드] 안드로이드 이중 어댑터(이중 리사이클러뷰) 구현 메모 (feat. 데이터바인딩)
막무가내막내 2020. 8. 31. 20:09728x90
[2021-04-14 업데이트]
안녕하세요 ㅎㅎ
이중 어댑터 (이중 리사이클러뷰)를 데이터바인딩과 엮어서 구현해본거는 처음이라 기록용!!! 으로 남깁니다. (바빠서 따로 설명은 달지 않겠습니다 .ㅠㅠ)
디자이너분이 밑과같이 하나의 아이템리스트에 해쉬태그가 한줄로 좌우 스크롤을 할 수 있게 해달라고 하셨습니다.
그래서 큰아이템리스트(사진과 글)과 그안에 리사이클러뷰를 horiziontal 로 하나 더 두어 이중 어댑터(리사이클러뷰) 구조로 구현을 했습니다. 간단히 설명드리면 처음 어댑터에서 VIewHodler 쪽에서 어댑터를 생성해 해쉬태그어댑터(두번쨰어댑터)에 세팅을 해주는 형식으로 구현했습니다.
먼저 큰 아이템 xml 과 어댑터입니다.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="item"
type="com.mtjin.nomoneytrip.data.home.Product" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_12dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="@dimen/radius_16dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_item_product_radius_16dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="@dimen/height_180dp"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
bind:urlImage="@{item.image}"
tools:src="@drawable/busan" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_12dp"
android:layout_marginEnd="@dimen/margin_12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_save_white_off" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/padding_16dp"
app:layout_constraintTop_toBottomOf="@id/iv_image">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_16dp"
android:layout_marginTop="@dimen/margin_16dp"
android:layout_marginEnd="@dimen/margin_16dp"
android:ellipsize="end"
android:maxLines="2"
android:text="@{item.content}"
android:textColor="@color/colorBlack2D2D"
android:textSize="@dimen/text_size_14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="무전숙박 상품 타이틀입니다.\n 재미있게
두줄까지 작성 가능합니다." />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_hash_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_24dp"
android:orientation="horizontal"
android:paddingStart="@dimen/padding_16dp"
android:paddingEnd="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_content"
bind:setItems="@{item.hashTagList}"
tools:listitem="@layout/item_product_hash_tag" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
package com.mtjin.nomoneytrip.views.home
import android.content.Context
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.mtjin.nomoneytrip.R
import com.mtjin.nomoneytrip.data.home.Product
import com.mtjin.nomoneytrip.databinding.ItemProductBinding
import com.mtjin.nomoneytrip.utils.getMyDrawable
import com.mtjin.nomoneytrip.utils.uuid
class HomeProductAdapter(
private val context: Context,
private val itemClick: (Product) -> Unit,
private val favoriteClick: (Product) -> Unit
) :
RecyclerView.Adapter<HomeProductAdapter.ViewHolder>() {
private val items: ArrayList<Product> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding: ItemProductBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.item_product,
parent,
false
)
val viewHolder = ViewHolder(binding)
binding.root.setOnClickListener {
itemClick(items[viewHolder.adapterPosition])
}
binding.ivFavorite.setOnClickListener {
items[viewHolder.adapterPosition].let {
if (it.favoriteList.contains(uuid)) {
val img: Drawable? = context.getMyDrawable(R.drawable.ic_save_white_off)
binding.ivFavorite.setImageDrawable(img)
items[viewHolder.adapterPosition].favoriteList.remove(uuid)
} else {
val img: Drawable? = context.getMyDrawable(R.drawable.ic_save_on)
items[viewHolder.adapterPosition].favoriteList.add(uuid)
binding.ivFavorite.setImageDrawable(img)
}
favoriteClick(items[viewHolder.adapterPosition])
}
}
return viewHolder
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
items[position].let {
holder.bind(it)
}
}
inner class ViewHolder(private val binding: ItemProductBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Product) {
val adapter = ProductHashTagAdapter()
binding.rvHashTags.adapter = adapter
binding.item = item
if (item.favoriteList.contains(uuid)) {
val img: Drawable? = context.getMyDrawable(R.drawable.ic_save_on)
binding.ivFavorite.setImageDrawable(img)
}else{
val img: Drawable? = context.getMyDrawable(R.drawable.ic_save_white_off)
binding.ivFavorite.setImageDrawable(img)
}
binding.executePendingBindings()
}
}
fun addItems(items: List<Product>) {
this.items.addAll(items)
notifyDataSetChanged()
}
fun addItem(item: Product) {
this.items.add(item)
notifyDataSetChanged()
}
fun clear() {
this.items.clear()
notifyDataSetChanged()
}
}
그 안에 해쉬태그 뷰와 어댑터입니다.
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="item"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_8dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_hash_tag_orange_radius_8dp"
android:text="@{item}"
android:textColor="@color/colorOrangeF79256"
android:textSize="@dimen/text_size_14sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="#농촌 봉사" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
package com.mtjin.nomoneytrip.views.home
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.mtjin.nomoneytrip.R
import com.mtjin.nomoneytrip.databinding.ItemProductHashTagBinding
class ProductHashTagAdapter :
RecyclerView.Adapter<ProductHashTagAdapter.ViewHolder>() {
private val items: ArrayList<String> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding: ItemProductHashTagBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.item_product_hash_tag,
parent,
false
)
return ViewHolder(
binding
)
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
items[position].let {
holder.bind(it)
}
}
class ViewHolder(private val binding: ItemProductHashTagBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: String) {
binding.item = item
binding.executePendingBindings()
}
}
fun addItems(items: List<String>) {
this.items.addAll(items)
notifyDataSetChanged()
}
fun addItem(item: String) {
this.items.add(item)
notifyDataSetChanged()
}
fun clear() {
this.items.clear()
notifyDataSetChanged()
}
}
댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!
728x90
'안드로이드 > 코틀린 & 아키텍처 & Recent' 카테고리의 다른 글
[안드로이드] 새로운 저장소 Jetpack DataStore (feat. Sharedpreferences 를 대체) (2) | 2020.09.03 |
---|---|
[안드로이드] 안드로이드 AlarmManager 와 WorkManager 사용하여 10분전 알림 만들기 (8) | 2020.09.02 |
[안드로이드] 한국관광공사 API Service key error 처리 (SERVICE KEY IS NOT REGISTERED ERROR) (0) | 2020.08.30 |
[안드로이드] 데이터바인딩 xml onclick 한글 파라미터 오류 해결 (2) | 2020.08.29 |
[안드로이드] Android Jetpack WorkManager 백그라운드 작업처리 정리 (2) | 2020.08.19 |
Comments