I want to implement a sort/filter kind of system where:
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
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.