Я создаю вложенное горизонтальное представление переработчика для указания списка категорий во фрагменте. Я все настроил правильно (см. Код ниже). Тем не менее, когда я прокручиваю изначально, и просмотр рециркулятора переходит к SCROLL_STATE_IDLE, я не могу прокрутить в противоположном направлении.
Но , если я продолжу прокручивать вправо, то go влево, не поднимая мой палец работает нормально. Не уверен, почему просмотрщик мусора застревает.
item_category_container. 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">
<data>
<variable
name="categories"
type="io.example.model.Categories" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:paddingTop="16dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@{categories.titleId}"
android:textAppearance="?attr/textAppearanceHeadline5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/whats_your_job_interest" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
item_category. 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">
<data>
<variable
name="category"
type="io.example.model.Category" />
</data>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_view"
android:layout_width="154dp"
android:layout_height="160dp"
android:background="?attr/colorSurface"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
app:rippleColor="@android:color/transparent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_mid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.55" />
<ImageView
android:id="@+id/category_image_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="false"
android:focusable="false"
app:glideCenterCrop="@{true}"
app:glideSrc="@{category.resId}"
app:layout_constraintBottom_toTopOf="@+id/guideline_mid"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription"
tools:scaleType="centerCrop"
tools:src="@drawable/paris_1" />
<TextView
android:id="@+id/title_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:text="@{category.titleId}"
android:textAppearance="?attr/textAppearanceSubtitle2"
android:textStyle="bold"
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</layout>
CategoryBinderView
class ExploreCategoryViewBinder(
private val eventListener: ExploreEventListener
) : ItemViewBinder<Categories, CategoriesViewHolder>(Categories::class.java) {
override fun createViewHolder(parent: ViewGroup): CategoriesViewHolder {
val holder = CategoriesViewHolder(
ItemCategoriesContainerBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
)
holder.binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == SCROLL_STATE_IDLE) {
saveInstanceState(holder)
}
}
})
return holder
}
override fun bindViewHolder(model: Categories, viewHolder: CategoriesViewHolder) {
viewHolder.bind(model, recyclerViewManagerState)
}
override fun getViewItemType(): Int = R.layout.item_categories_container
override fun areItemsTheSame(oldItem: Categories, newItem: Categories): Boolean = true
override fun areContentsTheSame(oldItem: Categories, newItem: Categories) = oldItem == newItem
override fun onViewRecycled(viewHolder: CategoriesViewHolder) {
saveInstanceState(viewHolder)
}
override fun onViewDetachedFromWindow(viewHolder: CategoriesViewHolder) {
saveInstanceState(viewHolder)
}
fun saveInstanceState(viewHolder: CategoriesViewHolder) {
if (viewHolder.adapterPosition == NO_POSITION) {
return
}
recyclerViewManagerState = viewHolder.getLayoutManagerState()
}
}
class CategoriesViewHolder(
val binding: ItemCategoriesContainerBinding
) : ViewHolder(binding.root) {
fun bind(category: Categories) {
binding.categories = category
val categoryAdapter = CategoryAdapter()
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(context, HORIZONTAL, false)
adapter = categoryAdapter
setRecycledViewPool(recycledViewPool)
}
layoutManager = binding.recyclerView.layoutManager
categoryAdapter.submitList(category.categories)
binding.executePendingBindings()
}
}
class CategoryAdapter : ListAdapter<Category, CategoryItemViewHolder>(CategoryDiff) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryItemViewHolder {
return CategoryItemViewHolder(
ItemCategoryBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
)
}
override fun onBindViewHolder(holder: CategoryItemViewHolder, position: Int) {
holder.bind(getItem(position))
}
}
class CategoryItemViewHolder(
private val binding: ItemJobCategoryBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(category: Category) {
binding.category = category
}
}
object CategoryDiff : DiffUtil.ItemCallback<Category>() {
override fun areItemsTheSame(oldItem: Category, newItem: Category) =
oldItem.titleId == newItem.titleId
override fun areContentsTheSame(oldItem: Category, newItem: Category) = oldItem == newItem
}