0

I'm trying to adopt PagedList to my app. One of the functionality I want is the ability to handle button click event within list item.

I was thinking to utilize ViewModel to listen for the click event and taken from the example https://medium.com/@star_zero/singleliveevent-livedata-with-multi-observers-384e17c60a16, I was successfully getting the click event.

so I have,

LivePagedListBuilder(DeviceDataSourceFactory(), defaultConfig)
    .build()
    .observe(this, Observer { list ->
        // here is where I have Observer for the click event
        // for example, list?.forEach { it.event.observe(...) }
        // but this block isn't called everytime
        adapter.submitList(list)  
    })

As the comment above, I don't always get notified when new item is added to the list. I guess I only got it once from loadInitial and once from loadAfter. After ref is linked, PagedList handles updating the list itself without notifying the Observer. Therefor, I can't correctly setup click event Observer. Any help would be appreciated. been blocked for more than a week. Thanks!

user1865027
  • 3,505
  • 6
  • 33
  • 71

1 Answers1

1

You can always pass the reference to your OnClickListener to your Adapter class.

For example:

//Reference of click listener in your Adapter class
//Initialise clickListener in adapter's init method, You can pass ViewModel's reference to the adapter as the reference of YOUR_LISTENER_IMPL
val clickListener : YOUR_LISTENER_IMPL

//ViewHolder class
class YOUR_VIEW_HOLDER(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(data: YOUR_DATA_TYPE, clickListener: (YOUR_DATA_TYPE) -> Unit) {
        itemView.setOnClickListener { clickListener(data)}
    }
}

//onBindViewHolder method inside Adapter
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    // Populate ViewHolder with data that corresponds to the position in the list
    // which we are told to load
    (holder as YOUR_VIEW_HOLDER).bind(DATA_SOURCE_LIST[position], clickListener)
}

Then while initialising your adapter, you can send the clickListener object via constructor. This way all your ViewHolder instances will always have a clickListener and you won't be missing any click events, when the items gets added into the list.
I hope this helps.

Salman Khakwani
  • 6,684
  • 7
  • 33
  • 58
  • Thanks for the suggestion! I know `ViewHolder` is my last bet if I can't find any solution. I still prefer to have click event happen in `ViewModel`. easier for me to use – user1865027 Aug 16 '18 at 05:29
  • You can still have your `OnClickListener` in your `ViewModel`, All you need to do is implement the `OnClickListener` in your `ViewModel` class and send the instance of `ViewModel` class to your `adapter` instance. – Salman Khakwani Aug 16 '18 at 06:31
  • wait...no, the point is I can't always get `ViewModel` as originally stated in the question. Otherwise I could've just use it in `Activity`. How can I make sure adapter has has all `ViewModel` – user1865027 Aug 17 '18 at 06:30
  • Please share the code that you are currently using for the `OnClickListener`, with that I will be able to provide you an exact solution. – Salman Khakwani Aug 17 '18 at 07:15
  • Also, I assume that you would have been initialising the adapter once and then adding values to it's data source later (when paginating). That way, your `OnClickListener` will always be available inside of the adapter (that you set upon initialisation) and from there it will be passed to the `ViewHolder` objects. – Salman Khakwani Aug 17 '18 at 07:48