stfalcon-studio / ChatKit

Android library. Flexible components for chat UI implementation with flexible possibilities for styling, customizing and data management. Made by Stfalcon
http://stfalcon.com
Apache License 2.0
3.68k stars 830 forks source link

Insert at specific position #228

Open hermannkuschke opened 5 years ago

hermannkuschke commented 5 years ago

Hi, could you please advise on what the easiest way is to insert an item at a specific position rather than at the end or start of the list?

knaeckeKami commented 5 years ago

I had the same problem. I ended up implementing my own adapter, that inherits from the default MessagesListAdapter, with this method:

fun updateItems(rawItems : List<DisplayableChatMessage>) {
    val oldItems = this.items

    this.items = mutableListOf()
    generateDateHeaders(rawItems)

    DiffUtil.calculateDiff(object : DiffUtil.Callback() {
        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldItems[oldItemPosition].item == items[newItemPosition].item
        }

        override fun getOldListSize(): Int = oldItems.size

        override fun getNewListSize(): Int = items.size

        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return true
        }

    }).dispatchUpdatesTo(this)

}`

(Kotlin, but should be easily translatable to Java. Note that you need to implement the .equals() method on your message objects, preferably making it fast by comparing only the id, so that DiffUtil needs to do less work )

You just pass your new List of Messages to the adapter, the adapter figures of the new state efficiently using DiffUtil, you even get nice animations for free using this approach.

hermannkuschke commented 5 years ago

Wow, thank you so much for the quick reply. Testing it as we speak. I appreciate this very much!

knaeckeKami commented 5 years ago

Yeah, this method works for me now, but it's not very efficient if there are thousands of messages and you just want to insert one, because it re-generates the date headers each time. Unfortunately, I don't think it's possible to do this efficiently without forking the library and making the adapter more open to inheritance. If you need a more granular approach too, you can check out my fork:

https://github.com/knaeckeKami/ChatKit

I just made the message-wrapper class public, so the adapter can basically do everything. It's on jitpack.

fukemy commented 3 years ago

@knaeckeKami hello, i didn't see ur commit to see what difference with origin version, so i can not see how did u implement code, please help thanks