【问题标题】:Android Paging 3 clear recyclerview on invalidate()Android Paging 3 在 invalidate() 上清除 recyclerview
【发布时间】:2021-11-05 07:32:11
【问题描述】:

我有一个可以应用过滤器的分页列表。用户应用过滤器后,recyclerview 应该在加载页脚中显示 0 个项目,直到它加载第一个项目并触发 LoadResul.Error 以防没有可显示的内容。

页脚工作正常,但您仍然可以看到调用 .invalidate() 之前存在的数据,并且您会看到该数据,直到它从后端获得新的响应(如果您的网络不好,这可能需要一些时间) .并且如果出现错误,旧项目仍然存在,并且会出现错误页脚。

关于如何实现这一点的任何想法?

我也在使用带有 RxJava 的库,所以这里是 DataSource 代码:


    override fun getRefreshKey(state: PagingState<Int, Event>): Int = 1

    override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Event>> {
        val key = params.key ?: 1

        return repository.getCityEvents(
            cityId = globalData.currentCityId,
            start = selectedDates?.start?.toApiFormat(),
            end = selectedDates?.end?.toApiFormat(),
            pageNo = key,
            categories = categoryFilters
        )
            .map { it.content }
            .map { toLoadResult(it, params) }
            .onErrorReturn { LoadResult.Error(it) }
    }

    private fun toLoadResult(data: List<Event>, params: LoadParams<Int>): LoadResult<Int, Event> {
        val currentKey = params.key ?: 1

        return if (data.isEmpty() && currentKey == 1)
            LoadResult.Error(NoEventsException())
        else
            LoadResult.Page(
                data = data,
                prevKey = null,
                nextKey = if (data.size < params.loadSize) null else currentKey + 1
            )
    }

【问题讨论】:

    标签: android rx-java2 android-paging android-paging-library android-paging-3


    【解决方案1】:

    首先,您需要将LoadStateAdapter 添加到您的PagingDataAdapter,如下所示:

    item_paging_loading.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="12dp">
    
        <ProgressBar
            android:id="@+id/progressbar"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_gravity="center_horizontal" />
    
        <TextView
            android:id="@+id/textError"
            style="@style/TextSmall"
            android:layout_gravity="center"
            android:gravity="center"
            android:visibility="gone"
            tools:text="Some Error Occurred"
            tools:visibility="visible" />
    
        <TextView
            android:id="@+id/buttonRetry"
            style="@style/TextMedium"
            android:layout_gravity="center"
            android:background="?selectableItemBackground"
            android:padding="@dimen/_5dp"
            android:text="@string/retry"
            android:textColor="@color/colorAccent" />
    </androidx.appcompat.widget.LinearLayoutCompat>
    

    PaginationLoadStateAdapter.kt

    class PaginationLoadStateAdapter(
        val retry: () -> Unit
    ) : LoadStateAdapter<PaginationLoadStateAdapter.PassengersLoadStateViewHolder>() {
    
        inner class PassengersLoadStateViewHolder(
            private val binding: ItemPagingLoadingBinding,
            private val retry: () -> Unit
        ) : RecyclerView.ViewHolder(binding.root) {
            fun bind(loadState: LoadState) {
                if (loadState is LoadState.Error) {
                    binding.textError.text = loadState.error.localizedMessage
                }
                binding.progressbar.visible(loadState is LoadState.Loading)
                binding.buttonRetry.visible(loadState is LoadState.Error)
                binding.textError.visible(loadState is LoadState.Error)
                binding.buttonRetry.setOnClickListener {
                    retry()
                }
            }
        }
    
        override fun onBindViewHolder(
            holder: PassengersLoadStateViewHolder,
            loadState: LoadState
        ) {
            holder.bind(loadState)
        }
    
        override fun onCreateViewHolder(
            parent: ViewGroup,
            loadState: LoadState
        ) = PassengersLoadStateViewHolder(
            ItemPagingLoadingBinding.inflate(
                LayoutInflater.from(parent.context), parent, false
            ),
            retry
        )
    }
    

    PagingDataAdapter添加页眉和页脚的扩展功能

    fun <T : Any, V : RecyclerView.ViewHolder> PagingDataAdapter<T, V>.withLoadStateAdapters(
        header: LoadStateAdapter<*>,
        footer: LoadStateAdapter<*>
    ): ConcatAdapter {
        addLoadStateListener { loadStates ->
            header.loadState = loadStates.refresh
            footer.loadState = loadStates.append
        }
    
        return ConcatAdapter(header, this, footer)
    }
    

    你需要像这样为你的 RV 设置页眉和页脚:

    binding.list.adapter = pagingDataAdapter.withLoadStateAdapters(
                    header = PaginationLoadStateAdapter { adapterSimpleOffers.retry() },
                    footer = PaginationLoadStateAdapter { adapterSimpleOffers.retry() }
                )
    

    用户应用过滤器后,您可以提交空数据以显示 0 个项目,然后再次加载您的分页。

    pagingDataAdapter.submitData(lifecycle, PagingData.empty())
    loadData()//load your data
    

    【讨论】:

    • 嘿@BotiraliKozimov 你能帮我解决这个问题吗issue
    猜你喜欢
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2020-12-15
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多