Sunday, 20 December 2020

How can I refresh the data source of ListAdapter at once after I launch submitList in Android?

I use ListAdapter as the source of a RecyclerView, it will display a list of MVoice. The data source is mHomeViewModel.listVoiceBySort, it's LiveData<List<MVoice>>, you can see Code A.

After I added a record, mHomeViewModel.listVoiceBySort.observe will be launched, myAdapter.submitList(it) will be launched too.

But I found, the latest mHomeViewModel.listVoiceBySort isn't applied to ListAdapter, you can see Log A.

How can I refresh the data source of ListAdapter at once after I launch submitList ?

Log A

E/My: itemCount: 13 it: 14 CurrentList:13

Code A

binding.recyclerViewVoice.adapter = myAdapter
mHomeViewModel.listVoiceBySort.observe(this.viewLifecycleOwner) {
   myAdapter.submitList(it)
   Log.e("My","itemCount: "+myAdapter.itemCount+ " it: "+it.size+ " CurrentList:"+myAdapter.currentList.size)

}

class VoiceAdapters (private val aHomeViewModel: HomeViewModel, private val mPlay: PlayInterface):
        ListAdapter<MVoice, VoiceAdapters.VoiceViewHolder>(MVoiceDiffCallback()) {

    private lateinit var mContext: Context
    private lateinit var mLifecycleOwner:LifecycleOwner

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VoiceViewHolder {
        mContext = parent.context
        mLifecycleOwner = mContext as LifecycleOwner

        return VoiceViewHolder(
            LayoutVoiceItemBinding.inflate(LayoutInflater.from(parent.context), parent, false).also {              
               it.lifecycleOwner = mLifecycleOwner
               it.aHomeViewModel = aHomeViewModel
            }
        )
    }

    override fun onBindViewHolder(holder: VoiceViewHolder, position: Int) {
        val inputMVoice = getItem(position)
        holder.bind(inputMVoice)
    }

   
    inner class VoiceViewHolder (private val binding: LayoutVoiceItemBinding):
          RecyclerView.ViewHolder(binding.root) {
       
        fun bind(inputMVoice: MVoice) {                        
            binding.amVoice = inputMVoice          
            binding.executePendingBindings()
        }
    }

}


class MVoiceDiffCallback : DiffUtil.ItemCallback<MVoice>() {
    override fun areItemsTheSame(oldItem: MVoice, newItem: MVoice): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItem: MVoice, newItem: MVoice): Boolean {
        return oldItem == newItem
    }
}

Added Content

To Tenfour04: Thanks!

The following Code B is how to get the LiveDate mHomeViewModel.listVoiceBySort.

Code B

class HomeViewModel(val mApplication: Application, private val mDBVoiceRepository: DBVoiceRepository) : AndroidViewModel(mApplication) {

    private val _listVoiceBySort=_sortBy.switchMap {
        mDBVoiceRepository.listVoiceBySort(it)
    }

    val listVoiceBySort: LiveData<List<MVoice>> =_listVoiceBySort
    ...
}

class DBVoiceRepository private constructor(private val mDBVoiceDao: DBVoiceDao){

    private val _isHaveRecord= MutableLiveData<Boolean>(false)
    val isHaveRecord:LiveData<Boolean> =_isHaveRecord

    fun listVoiceBySort(aSortBy: ESortBy): LiveData<List<MVoice>> {
        var query=when (aSortBy){
            ESortBy.StartPriority ->
               "SELECT * FROM voice_table ORDER BY starred desc, createdDate desc"
            ESortBy.DateDesc ->
               "SELECT * FROM voice_table ORDER BY createdDate desc"
            ESortBy.DateAsc ->
               "SELECT * FROM voice_table ORDER BY createdDate"
            ESortBy.TitleDesc ->
               "SELECT * FROM voice_table ORDER BY title desc"
            ESortBy.TitleAsc ->
               "SELECT * FROM voice_table ORDER BY title"
        }
        return mDBVoiceDao.runtimeQuery(SimpleSQLiteQuery(query)).map {
            _isHaveRecord.value =!it.isNullOrEmpty()
            it
        }
    }
    ...
}

@Dao
interface DBVoiceDao{   
   @RawQuery(observedEntities = [MVoice::class])
   fun  runtimeQuery(sortQuery: SupportSQLiteQuery): LiveData<List<MVoice>>
   ...
}


abstract class DBVoiceDatabase : RoomDatabase() {
   ...
}


from How can I refresh the data source of ListAdapter at once after I launch submitList in Android?

No comments:

Post a Comment