마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

이중 리사이클러뷰를 ViewType을 활용하는데 horizontal 적용이 안됩니다.

0 추천

안녕하세요 . 세로방향 리사이클러뷰 안에 카테고리별 데이터를 담을 가로방향 리사이클러뷰를 하나 더 넣었습니다. 여기서 문제는 잘 돌아가던 코드가, VIewType으로 변경하니 가로방향이 아닌 세로 방향으로 나온다는 겁니다.

XML에서 

android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

이렇게도 넣어보고, 코드로도 조작해 보았으나 계속 세로방향으로 되곤합니다. 혹시 VIewType 바꾸게 되면 추가적으로 설정해줘야 할 게 있나요?

<리사이클러뷰 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:tools="http://schemas.android.com/tools">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_saved_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->newsClickListener.onClick(news)}"
            android:orientation="horizontal"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:listitem="@layout/item_saved" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

<그 안에 담길 item>

<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="160dp"
android:layout_height="240dp"
android:onClick="@{()->newsClickListener.onClick(news)}"
android:padding="8dp">

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_saved_image"
imageUrl="@{news.urlToImage}"
android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="@style/NewsImageView"
tools:src="@tools:sample/avatars" />

<TextView
android:id="@+id/tv_saved_title"
style="@style/NewsTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:lineHeight="16sp"
android:text="@{news.title}"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_saved_image"
tools:text="Title" />

<TextView
android:id="@+id/tv_saved_published_at"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:text="@{StringExtensionsKt.formatDate(news.publishedAt)}"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_saved_title"
tools:text="2023/12/25" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>


<바깥쪽 어탭터>

class SavedListAdapter(private val clickListener: NewsClickListener) :
    ListAdapter<SavedArticle, RecyclerView.ViewHolder>(diffUtil) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            VIEW_TYPE_CATEGORY -> SavedCategoryViewHolder.from(parent)
            else -> SavedItemViewHolder.from(parent)
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is SavedCategoryViewHolder -> holder.bind(getItem(position) as SavedCategory)
            is SavedItemViewHolder -> holder.bind(getItem(position) as TopHeadlineList, clickListener)
        }
    }

    override fun getItemViewType(position: Int): Int {
        return when (getItem(position)) {
            is SavedCategory -> VIEW_TYPE_CATEGORY
            is TopHeadlineList -> VIEW_TYPE_ITEM
        }
    }

    class SavedCategoryViewHolder(private val binding: ItemCategoryBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(savedCategory: SavedCategory) {
            binding.savedCategory = savedCategory
        }

        companion object {
            fun from(parent: ViewGroup): SavedCategoryViewHolder {
                return SavedCategoryViewHolder(
                    ItemCategoryBinding.inflate(
                        LayoutInflater.from(parent.context),
                        parent,
                        false
                    )
                )
            }
        }
    }
    class SavedItemViewHolder(private val binding: ItemSavedListBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(news: TopHeadlineList, clickListener: NewsClickListener) {
            binding.topHeadlineList = news
            binding.newsClickListener = clickListener
            binding.rvSavedList.apply {
                adapter = SavedItemAdapter(clickListener).apply {
                    submitList(news.newsList)
                }
            }
        }
        companion object {
            fun from(parent: ViewGroup): SavedItemViewHolder {
                return SavedItemViewHolder(
                    ItemSavedListBinding.inflate(
                        LayoutInflater.from(parent.context),
                        parent,
                        false
                    )
                )
            }
        }
    }

    companion object {

        private const val VIEW_TYPE_CATEGORY = 0
        private const val VIEW_TYPE_ITEM = 1
}

 

<아이템 어댑터>

class SavedItemAdapter(private val clickListener: NewsClickListener) :
    ListAdapter<News, SavedItemAdapter.SavedItemViewHolder>(diffUtil) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SavedItemViewHolder {
        return SavedItemViewHolder.from(parent)
    }
    override fun onBindViewHolder(holder: SavedItemViewHolder, position: Int) {
        holder.bind(currentList[position], clickListener)
    }

    class SavedItemViewHolder(private val binding: ItemSavedBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(news: News, clickListener: NewsClickListener) {
            binding.news = news
            binding.newsClickListener = clickListener
        }
        companion object {
            fun from(parent: ViewGroup): SavedItemViewHolder {
                return SavedItemViewHolder(
                    ItemSavedBinding.inflate(
                        LayoutInflater.from(parent.context),
                        parent,
                        false
                    )
                )
            }
        }
    }
}

 

리사이클러뷰 어댑터와 아이템 어댑터를 연결하는 부분은 노란색으로 표시된 부분입니다.

진짜 다양하게 시도 했는데 도저히 안되네요 ㅠㅠㅠ

재주 (170 포인트) 님이 2023년 12월 31일 질문

1개의 답변

0 추천
 
채택된 답변
Nested RecyclerView를 설정하는 부분이 안보이네요. 리사이클러뷰 어댑터의 뷰홀더 안에서 리사이클러뷰가 들어가는 아이템이 나올경우 어댑터를 세팅해주셔야하는데, 그 부분이 보이질 않네요.
spark (227,530 포인트) 님이 1월 2일 답변
재주님이 1월 11일 채택됨
SavedItemViewHolder의 버튼 클릭 리스너에 Nested Recycler뷰를 설정하는 코드가 있는 것 같은데, 버튼 클릭이벤트에 넣어야 하는 이유가 있는지 모르겠네요.
...