4

検索されたアイテムのリストを表示する検索フラグメントがあります。ユーザーが何かを入力すると、その文字列を新しいクエリ パラメータとして url に渡し、ページング 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)
            }
        }
    }

url ( を変更することによるこのソリューションではshowPostList(newUrl)、リストは変更されずに残ります。おそらく、viewModel でキャッシュされたリストを使用します。

別の解決策はshowPostList(initUrl)、 in onViewCreatedof fragment を使用してから、パラメーターを変更してblewメソッドを使用することです。

//fragment
fun changePostList(url: String) {
        viewModel.postListUrl = url
        postListAdapter.refresh()
    }

これは機能しますが、古いリストと新しいリストに共通のアイテムがある場合、新しいリストは最後の共通の表示アイテムに表示されます。たとえば、古いリストの 5 番目の項目が新しいリストの 7 番目と同じ場合、リストを変更して新しいリストを表示すると、最初の項目ではなく 7 番目の項目から開始されます。

ここで別の解決策を見つけました:

//viewModel
val postListUrlFlow = MutableStateFlow("")
    val postList = postListUrlFlow.flatMapLatest { query ->
        Pager(PagingConfig(pageSize = 20)) {
            PostPagingSource(postRepository, query)
        }.flow.cachedIn(viewModelScope)
    }

//fragment
fun showPostList(url: String) {
        postListAdapter.submitData(lifecycle, PagingData.empty())
        viewModel.postListUrlFlow.value = url
        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.postList.collectLatest {
                postListAdapter.submitData(it)
            }
        }
    }

ただし、このリストを使用すると、フラグメントに戻って更新され、Recyclerview状態が変化することがあります。

4

1 に答える 1

0
class MyViewModel:ViewModel(){
  private val _currentQuery = MutableLiveData<String>()
  val currentQuery:LiveData<String> = _currentQuery


  val users = _currentQuery.switchMap { query->
      Pager(PagingConfig(pageSize = 20)) {
      PostPagingSource(postRepository, query)
  }.livedata.cachedIn(viewModelScope)

  }


  fun setCurrentQuery(query: String){
       _currentQuery.postValue(query)
  }
}

の使用により

スイッチマップ

クエリが変更されるたびに新しい結果を取得でき、古いデータが置き換えられます。

于 2022-01-22T11:17:14.817 に答える