标签: android-paging

如何使用体系结构组件分页库停止在回收器视图上闪烁

我有一个类似聊天的活动,我使用带有PagedListAdaper的RecyclerView来加载一堆消息.我正在使用PositionalDataSource来加载数据.加载它的自我工作正常但是当我发送消息时,我使我的数据源无效并且列表被重新制作.我的问题是,当它这样做时它会闪烁:

这就是它的样子

我尝试添加setHasStableIds(true)并重写getItemId,它可以在一个简单的适配器上工作,但它似乎在这里不起作用.我似乎也无法将项添加到getCurrentList(),因为它不受支持.此外,我没有使用数据库,只是向服务器发出请求.

所以我的问题是,除了使数据源失效之外,还有更好的方法吗?有没有办法阻止列表在发送消息时闪烁?或者这个图书馆不适合我的聊天活动?

编辑:

我的差异回调

private val DIFF_CALLBACK: DiffCallback<MessageModel> = object : DiffCallback<MessageModel>() {
        override fun areItemsTheSame(@NonNull oldMessage: MessageModel, @NonNull newMessage: MessageModel) =
                oldMessage.id == newMessage.id


        override fun areContentsTheSame(@NonNull oldMessage: MessageModel, @NonNull newMessage: MessageModel) =
                oldMessage.equals(newMessage)
    }
Run Code Online (Sandbox Code Playgroud)

Edit2我修复了它:

所以我设法通过使用PagedListAdapterHelper并在加载项目后设置它的列表来修复它:

private var mHelper: PagedListAdapterHelper<MessageModel>? = null

init {
    mHelper = PagedListAdapterHelper(this, DIFF_CALLBACK)
    setHasStableIds(true)
}
fun setList(pagedList: PagedList<MessageModel>) {
    pagedList.addWeakCallback(pagedList.snapshot(), object:PagedList.Callback() {
        override fun onChanged(position: Int, count: Int) {

        }

        override fun onInserted(position: Int, count: Int) {
            mHelper?.setList(pagedList) …
Run Code Online (Sandbox Code Playgroud)

android android-architecture-components android-paging

10
推荐指数
1
解决办法
1734
查看次数

Android Paging 3 如何过滤、排序和搜索我的数据

我正在尝试实现我正在使用 Room 的分页,我花了很长时间才意识到这一切都为我完成了,但我需要做的是能够过滤搜索并对我的数据进行排序。我想暂时将其保留为 LiveData,以便稍后交换为 Flow。\n我使用此方法来过滤搜索和排序,并且效果非常好,

\n
    @SuppressLint("DefaultLocale")\n    private fun searchAndFilterPokemon(): LiveData<List<PokemonWithTypesAndSpecies>> {\n        return Transformations.switchMap(search) { search ->\n            val allPokemon = repository.searchPokemonWithTypesAndSpecies(search)\n            Transformations.switchMap(filters) { filters ->\n                val pokemon = when {\n                    filters.isNullOrEmpty() -> allPokemon\n                    else -> {\n                        Transformations.switchMap(allPokemon) { pokemonList ->\n                            val filteredList = pokemonList.filter { pokemon ->\n                                pokemon.matches = 0\n                                val filter = filterTypes(pokemon, filters)\n                                filter\n                            }\n                            maybeSortList(filters, filteredList)\n                        }\n                    }\n                }\n                pokemon\n            }\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

这里有一些切换映射,第一个是响应搜索更新

\n
    var search: MutableLiveData<String> = getSearchState()\n
Run Code Online (Sandbox Code Playgroud)\n

第二个是响应过滤器更新

\n
    val filters: MutableLiveData<MutableSet<String>> …
Run Code Online (Sandbox Code Playgroud)

sorting android android-paging android-paging-3

10
推荐指数
1
解决办法
2万
查看次数

Android分页3:可以从PagingData&lt;T&gt;获取itemcount吗?

我怎样才能获得我PagingData<Product>持有的当前物品数量?我找到的唯一解决方案是调用,shopListAdapter.itemCount但这总是返回 0。

我想做的是:获取我的 PagingAdapter 当前显示的项目数量,将该值提交给我的 shopViewModel,然后在另一个片段(DialogFragment)中使用该值。PagingData<Product>或者:从我的视图模型内部获取项目数量

这是我目前的方法

主片段

@AndroidEntryPoint
class ShopFragment : Fragment(R.layout.fragment_shop), ShopAdapter.OnItemClickListener {
    private val shopViewModel: ShopViewModel by navGraphViewModels(R.id.nav_shop) { defaultViewModelProviderFactory }
    private var _shopBinding: FragmentShopBinding? = null
    private val shopBinding: FragmentShopBinding get() = _shopBinding!!
    @Inject lateinit var shopListAdapter: ShopAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _shopBinding = FragmentShopBinding.inflate(inflater, container, false)
        return shopBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        collectShopList()
    }

    private …
Run Code Online (Sandbox Code Playgroud)

paging android mvvm android-paging

10
推荐指数
1
解决办法
6764
查看次数

Android Paging 3 库:如何使用新参数更改列表?

我有一个显示搜索项目列表的搜索片段。如果用户输入某些内容,我会将该字符串作为新的查询参数传递给 url,并使用 paging 3 库获取新列表。

第一个解决方案是:

//viewModel
lateinit var postListUrl: String

    val postList: Flow<PagingData<Post>> = Pager(PagingConfig(pageSize = 20)) {
        PostPagingSource(postRepository, postListUrl)
    }.flow.cachedIn(viewModelScope)

//fragment
fun showPostList(url: String) {
        postListAdapter.submitData(lifecycle, PagingData.empty())
        viewModel.postListUrl = url
        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.postList.collectLatest {
                postListAdapter.submitData(it)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

通过此解决方案,通过更改 url ( showPostList(newUrl),列表保持不变。也许在 viewModel 中使用缓存列表。

另一种解决方案是:使用showPostList(initUrl)in onViewCreatedof 片段,然后通过更改参数使用 blow 方法:

//fragment
fun changePostList(url: String) {
        viewModel.postListUrl = url
        postListAdapter.refresh()
    }
Run Code Online (Sandbox Code Playgroud)

这项工作有效,但如果旧列表和新列表有共同的项目,新列表将显示在最后一个共同的可见项目上。例如,如果旧列表的第 5 个位置项与新列表的第 7 个位置项相同,则在列表更改以显示新列表后,它将从第 7 个位置开始,而不是第一个项目。

在这里找到了另一个解决方案:

//viewModel
val postListUrlFlow = MutableStateFlow("") …
Run Code Online (Sandbox Code Playgroud)

android android-paging kotlin-flow android-paging-3

10
推荐指数
1
解决办法
4191
查看次数

在 jetpack 撰写导航中返回导航时分页 3 列表自动刷新

我正在使用 Jetpack Compose,以及 Paging 3 库和 Jetpack Navigation。我面临的问题是我有一个 LazyList,它使用分页库从远程源获取数据。

视图模型

fun getImages(): Flow<PagingData<ObjectImage>> = Pager(
        PagingConfig(PAGE_SIZE, enablePlaceholders = false)
    ) { DataHome(RANDOM) }.flow.cachedIn(viewModelScope)
Run Code Online (Sandbox Code Playgroud)

主页视图

val images = viewModelHome.getImages().collectAsLazyPagingItems()
LazyColumn {
  ...
}
Run Code Online (Sandbox Code Playgroud)

现在发生的情况是,当我使用导航到另一个视图navHostController.navigate(),然后按返回返回到 HomeView 时...LazyColumn 会重置自身并开始再次从网络加载项目。

所以我被这个问题困扰了。我尝试在 viewModel 变量中手动缓存...虽然它有效,但它搞砸了 SwipeRefresh (停止显示刷新状态)

data.apply {
            when {
                // refresh
                loadState.refresh is LoadState.Loading -> {
                    ItemLoading()
                }

                // reload
                loadState.append is LoadState.Loading -> {...}

                // refresh error
                loadState.refresh is LoadState.Error -> {...}

                // reload error
                loadState.append is LoadState.Error -> {...}
            } …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack android-paging android-jetpack-navigation android-jetpack-compose

10
推荐指数
1
解决办法
7981
查看次数

在 NestedScrollView 中使用 PagedListAdapter

我有一个RecyclerViewPagedListAdapter.

当我把RecyclerView里面NestedScrollViewPagedList不能计算列表的末尾所以开始请求新数据的连续突发。

主要问题是我应该如何使用PagedListAdapterinside NestedScrollView

android-nestedscrollview android-paging

9
推荐指数
1
解决办法
693
查看次数

PageList.size始终为零

实际上,我是Paging Library的新手.这是一种情况,我正在从我的ViewModel观察PagedList,即使新闻列表出现在UI上也总是返回零.

 viewModel.getNews().observe(this, news -> {
                    swipeRefreshLayout.setRefreshing(false);
                    Timber.d("news size is %s",news.size());// **news size is 0**
                    adapter.submitList(news);
                });
Run Code Online (Sandbox Code Playgroud)

我的DataSource是

public class NewsDataSource extends ItemKeyedDataSource<String, News> {

    private MutableLiveData<Resource.Status> netStatusLive = new MutableLiveData<>();

   /*Hide Logic for clean purpose*/

    private List<News> localNewsList = new ArrayList<>();

    public NewsDataSource( /*Hide Logic for clean purpose*/) {
         /*Hide Logic for clean purpose*/
    }


    @Override
    public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull LoadInitialCallback<News> callback) {
        netStatusLive.postValue(Resource.Status.LOADING);
        localNewsList.clear();
        Disposable disposable =  /*Hide Logic for …
Run Code Online (Sandbox Code Playgroud)

android android-architecture-components android-jetpack android-paging

9
推荐指数
1
解决办法
668
查看次数

使用分页库和导航体系结构组件将recyclerview的状态保持在片段中

我正在使用jetpack的2个组件:分页库和导航。

就我而言,我有2个片段:ListMoviesFragment和MovieDetailFragment

当我滚动一定距离并单击recyclerview的电影项目时,MovieDetailFragment被附加,并且ListMoviesFragment在后堆栈中。然后我按返回按钮,ListMoviesFragment从后退堆栈中恢复。

该点是滚动位置,并且ListMoviesFrament的项被重置,就像第一次附加到其活动一样。因此,如何保持recyclerview的状态以防止这种情况?

换句话说,如何使用FragmentTransaction以传统方式但以现代方式(导航)保留整个片段的状态,例如隐藏/显示片段

我的示例代码:

片段布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         tools:context="net.karaokestar.app.SplashFragment">

<TextView
        android:id="@+id/singer_label"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="Ca s?"
        android:textColor="@android:color/white"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/btn_game_more"
        android:layout_centerVertical="true"
        android:background="@drawable/shape_label"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="@dimen/header_margin_bottom_list"
        android:textStyle="bold"
        android:padding="@dimen/header_padding_size"
        android:textAllCaps="true"/>


<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/list_singers"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)

片段Kotlin代码:

    package net.karaokestar.app
    import android.os.Bundle
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import androidx.fragment.app.Fragment
    import androidx.lifecycle.LiveData
    import androidx.lifecycle.Observer
    import androidx.navigation.fragment.findNavController
    import androidx.paging.LivePagedListBuilder
    import androidx.paging.PagedList
    import androidx.recyclerview.widget.LinearLayoutManager
    import kotlinx.android.synthetic.main.fragment_splash.*
    import net.karaokestar.app.home.HomeSingersAdapter
    import net.karaokestar.app.home.HomeSingersRepository

    class SplashFragment : Fragment() {

        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? …
Run Code Online (Sandbox Code Playgroud)

android android-recyclerview android-architecture-navigation android-paging

9
推荐指数
1
解决办法
2365
查看次数

如何使用 Android 分页库向 PagedList 添加标题

我尝试以正常方式添加标题(不同的视图类型,将数据计数增加 1 等),但分页列表滚动条跳转到列表底部。

从那以后,我遇到了 AsyncPagedListDiffer并试图实现它,但现在除了标题之外的所有项目都消失了。谁能看到我做错了什么?

    class MerchantHistoryAdapter : PagedListAdapter<MerchantHistoryResponse.Transaction, BaseViewHolder>(MerchantHistoryDiffUtilCallback()) {

    lateinit var listener: HistoryItemListAdapterListener
    lateinit var headerListener: HistoryItemHeaderListAdapterListener

    lateinit var networkStateListener: NetworkStateListAdapterListener
    private var networkState: NetworkState = NetworkState.LOADING

    val adapterCallback = AdapterListUpdateCallback(this)

    val listUpdateCallback = object : ListUpdateCallback {
        override fun onInserted(position: Int, count: Int) {
            adapterCallback.onInserted(position + 1, count)
        }

        override fun onRemoved(position: Int, count: Int) {
            adapterCallback.onRemoved(position + 1, count)
        }

        override fun onMoved(fromPosition: Int, toPosition: Int) {
            adapterCallback.onMoved(fromPosition + 1, toPosition + 1)
        } …
Run Code Online (Sandbox Code Playgroud)

android android-listview android-paging

9
推荐指数
1
解决办法
2267
查看次数

Jetpack Paging3 库对同一页面进行多次调用

我正在尝试按照Codelab使用房间数据库作为事实来源和 RemoteMediator 来实现 Jetpack paging 3 库。该应用程序查询 google books api,但由于某种原因,当我执行搜索时,它会多次调用同一页面。例如,当我在不滚动的情况下搜索 fire 时,我会在日志中看到以下内容:

D/BooksRepository: new search: fire
D/BooksRemoteMediator: title: fire, page: 0
I/okhttp.OkHttpClient: --> GET https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=0
I/okhttp.OkHttpClient: <-- 200 https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=0 (648ms, unknown-length body)
D/BooksRemoteMediator: title: fire, page: 1
I/okhttp.OkHttpClient: --> GET https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=1
I/okhttp.OkHttpClient: <-- 200 https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=1 (608ms, unknown-length body)
D/BooksRemoteMediator: title: fire, page: 0
I/okhttp.OkHttpClient: --> GET https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=0
I/okhttp.OkHttpClient: <-- 200 https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=0 (629ms, unknown-length body)
D/BooksRemoteMediator: title: fire, page: 1
I/okhttp.OkHttpClient: --> GET https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=1
I/okhttp.OkHttpClient: <-- 200 https://www.googleapis.com/books/v1/volumes?q=intitle%3Afire&key=AIzaSyBxHmT9nFCp9n2uOHkS3Gcq2OO3zbxaMrw&maxResults=40&startIndex=1 (843ms, …
Run Code Online (Sandbox Code Playgroud)

android android-paging android-paging-library

9
推荐指数
1
解决办法
2441
查看次数