Issue
I have a music list obtained from:
MusicDatabase.kt
override fun getContentProviderValue(): MutableList<Songs> {
val songList = mutableListOf<Songs>()
val collection = sdk29AndUp {
MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
} ?: MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
//Get songs from provider
context.contentResolver.query(
collection,
projection,
selection,
null,
PreferenceHelper.storeAllSongsSortOrder //Sort order.
).use { cursor ->
............
}
}
Using SharedPreference, I am storing and obtaining sort order like this:
PreferenceHelper.kt
//store allSongs sort order
var storeAllSongsSortOrder: String?
get() = preferences.getString(allSongSortOrder.first, allSongSortOrder.second)
set(value) = preferences.edit {
if (value != null) {
it.putString(allSongSortOrder.first, value)
}
}
I obtain the songList like this:
SongsFragment.kt
mainViewModel.mediaItems.observe(viewLifecycleOwner){ result->
when(result.status) {
Status.SUCCESS -> {
result.data?.let { songs ->
allSongsAdapter.songs = songs
........
}
In my songs fragment, when user clicks "Sort", a dropdown will appear with 2 options:
- Sort by name
- Sort by date
When user clicks sort by name, I do this:
SongsFragment.kt
PreferenceHelper.storeAllSongsSortOrder = Constants.SORT_TITLE
binding.rcvAllSongs.invalidate()
allSongsAdapter.notifyDataSetChanged()
When user clicks sort by date, I do this:
PreferenceHelper.storeAllSongsSortOrder = Constants.SORT_LAST_ADDED
binding.rcvAllSongs.invalidate()
allSongsAdapter.notifyDataSetChanged()
PROBLEM: The list is not updating real time as I select, I have to close the app and open before my list gets the selected sort order.
I want - when I click e.g "Sort by date" - The list should update immediately and display songs based on date added.
Solution
You can propably do something like this:
class YourFragment : Fragment {
private val allSongsAdapter = SongsAdapter()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
//init your views, bindins, view model and your recycler view adapter
//...
binding.recyclerView.adapter = allSongsAdapter
}
//...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mainViewModel.songList.observe(viewLifecycleOwner, { result ->
when (result.status) {
Status.SUCCESS -> {
allSongsAdapter.updateList(result.data)
}
}
})
//or whatever you have on your UI to change your filter
binding.sortFilter.setOnClickListener { filter ->
mainViewModel.updateSortFilter(filter)
}
//....
viewModel.initList()
}
}
class YourViewModel() : ViewModel() {
private var _unsortedSongList: List<String> = emptyList()
private val _songList = MutableLiveData<Songs>()
val songList: LiveData<Songs> = _songList
private lateinit var musicDatabase: MusicDatabase
init {
musicDatabase = //get the dependency or inject it from constructor
_unsortedSongList = musicDatabase.getContentProviderValue()
}
fun initList() {
_songList.value = sortSongs(PreferencesHelper.storeAllSongsSortOrder)
}
fun updateSortFilter(sortFilter: String) {
PreferencesHelper.storeAllSongsSortOrder = sortFilter
_songList.value = sortSongs(sortFilter)
}
private fun sortSongs(sortFilter: String): List<Songs> {
var sortedList: List<Songs> = emptyList()
switch (sortFilter) {
Constants.SORT_LAST_ADDED -> {
sortedList = _unsortedSongList.sortedBy { it.createdMillis }
}
Constants.SORT_LAST_ADDED -> {
sortedList = _unsortedSongList.sortedBy { it.name }
}
}
return sortedList
}
}
class SongsAdapter : RecyclerView.Adapter<SongItemAdapter.ViewHolder> {
private val songsList = mutableListOf<Songs>()
fun updateList(list: List<Songs>) {
songsList.clear()
songsList.addAll(list)
notifyDataSetChanged()
}
//.... the rest of your adapter and viewholder
}
Answered By - MatPag
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.