简体   繁体   中英

Change/Update Recycler View Item On Click of Item In Alert Builder Android

I want to implement a sort/filter kind of system where:

  • A user clicks an AlertBuilder, he sees "sort by name" and "sort by date".
  • On click of any of them, the recyclerview should be updated.

What I tried:

MusicDataBase

Where I am getting all songs and performing a sort based on user selection. (I am using dataStore to save user preference)

    fun getSongs(): List<Songs> {
    val preferenceStorageImpl = PreferenceStorageImpl(context)
    preferenceStorageImpl.sortOrder().asLiveData().observeForever(Observer {
       if (it == "name"){
            sortMusic = "${MediaStore.Audio.Media.DISPLAY_NAME} ASC"
        }
        else{
            sortMusic = "${MediaStore.Audio.Media.DATE_ADDED} DESC"
        }
    })
    //Get songs from provider
    context.contentResolver.query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        null,
        sortMusic //Sort in alphabetical or date order based on what was selected (Default - alphabetical).
    ).use

AllSongsAdapter

    private val diffCallback = object : DiffUtil.ItemCallback<Songs>() {
    override fun areItemsTheSame(oldItem: Songs, newItem: Songs): Boolean {          return oldItem.mediaId == newItem.mediaId
    }
    override fun areContentsTheSame(oldItem: Songs, newItem: Songs): Boolean {
        return oldItem.hashCode() == newItem.hashCode()
    }
}
 var songs: List<Songs>
    get() = differ.currentList
    set(value) = differ.submitList(value)

  .......//onbindviewholder
 override fun onBindViewHolder(holder: AllSongsViewHolder, position: Int) 
 {
    val song = songs[position]
    with(holder) {
        with(songs[position]) {
        .......
  }}

SongFragment

//Observe and show all songs
 mainViewModel.mediaItems.observe(viewLifecycleOwner){ result ->
        when(result.status){
            Status.SUCCESS -> {
                result.data?.let { songs ->
                    allSongsAdapter.songs = songs
                    allSongs = songs
                }
            }
            Status.ERROR -> Unit
            Status.LOADING -> Unit
        }
    }

//AlertBuilder, On click of sort by name or date
 private fun sortByName(){
    val sortOptionName = "name"
    storageViewModel.changeSortOption(sortOptionName)
    allSongsAdapter.notifyDataSetChanged()
}

private fun sortByDateAdded(){
    val sortOptionDate = "date"
    storageViewModel.changeSortOption(sortOptionDate)
    allSongsAdapter.notifyDataSetChanged()
}

StorageViewModel

class StorageViewModel @ViewModelInject constructor(private val 
preferenceStorage: PreferenceStorage) : ViewModel() {
val sortOrder = preferenceStorage.sortOrder().asLiveData()
fun changeSortOption(order: String) {
    viewModelScope.launch {
        preferenceStorage.setSortOrder(order)
    }
 }
}

I have also tried to call

  • allSongsAdapter.notifyDataSetChanged() from MusicDatabase when the value of the sortOption changes

eg

 if (it == "name"){
 sortMusic = "${MediaStore.Audio.Media.DISPLAY_NAME} ASC"
 allSongsAdapter.notifyDataSetChanged()
  }

Didn't work.

When I close the app, and open, the music list is sorted fine (According to the last sort option selected)

But it is not updated real time (The moment the user clicks sort by name or date)

You can recreate adapter every time when you want to update or in case you can use diffutil which is efficient compare to recreate whole recycler view or use invalidate() recycler view this will reinitalize it

recreate adapter as follows in kotlin:

private fun createAdapter() {
        val mLinearLayoutManager = GridLayoutManager(context, 2)
        mRecyclerViewMediaList.layoutManager = mLinearLayoutManager
        itemListSaved = getListFiles(
            File(
                Environment.getExternalStorageDirectory()
                    .toString() + DIRECTORY_TO_SAVE_MEDIA_NOW
            )
        )!!
          mRecyclerViewMediaList.adapter = mRecyclerViewMediaAdapte  
    }

call where you called notifydatasetchanged()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM