Search code examples
androidkotlinandroid-recyclerviewandroid-binding-adapter

RecyclerView not display all data when submiting list repeatedly


I am creating Notes app which display user Notes from local database. The app works great, but when I try to search (query) for notes multiple times, some data do not get displayed.

ScreenShot of app:

NotesViewModel

class NotesViewModel(private val database: NotesDao) : ViewModel() {
    fun searchNotes(string: String) = database.searchNote(string)
}

NotesFragment

binding.searchEditText.doOnTextChanged { text, _, _, _ ->
    notesViewModel.searchNotes("%$text%").observe(viewLifecycleOwner, {
        adapter.submitList(it)
        Log.v("NotesFragment: ", it.toString())           //Log return expected data
    })
}

NotesAdapter

class NotesAdapter(private val clickListener: NoteClickListener) : ListAdapter<Notes, NotesAdapter.NotesViewHolder>(NotesDiffCallBack()) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotesViewHolder {
        return NotesViewHolder.from(parent)
    }

    override fun onBindViewHolder(holder: NotesViewHolder, position: Int) {
        val item = getItem(position)
        holder.bind(clickListener, item)
    }
    
    class NotesViewHolder private constructor(private val binding: ListItemNotesBinding) : RecyclerView.ViewHolder(binding.root) {

        fun bind(clickListener: NoteClickListener, item: Notes) {
            binding.note = item
            binding.clickListener = clickListener
            binding.executePendingBindings()
        }
        .......
    }
}

BindingUtil

@BindingAdapter("noteTitle")
fun TextView.setNoteTitle(item: Notes?) {
    item?.let {
        Log.v("BindingUtil ", "title -> "+ it.noteTitle)     // Log return expected data
        when (it.noteTitle.isEmpty()) {
            true -> visibility = View.GONE
            false -> text = item.noteTitle
        }
    }
}

list_item_notes.xml

<data>
    <variable
        name="note"
        type="com.example.notes.db.Notes" />
<data/>
...
<TextView
    android:id="@+id/note_title_textview"
    app:noteTitle="@{note}" />

NotesDiffCallBack in NotesAdapter

class NotesDiffCallBack : DiffUtil.ItemCallback<Notes>() {
    override fun areItemsTheSame(oldItem: Notes, newItem: Notes): Boolean {
        return oldItem.noteId == newItem.noteId
    }

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

The 'note' data returned by database is correct. Even the Log.v() shows correct 'note' data in both 'NotesFragment' and 'BindingUtil', but do not gets displayed over UI. This is really annoying. Please help !!


Solution

  • Check which of these block inside when statement is getting called true or false

    If it executes false as expected then try to set

    visibilty = View.VISIBLE inside false block