Kotlin Secret recipe for Android (II): Recyclerview and Diffutil

Source: Internet
Author: User
Tags diff new set

Antonio Leiva

Time: Sep 12, 2016

Original link: http://antonioleiva.com/recyclerview-diffutil-kotlin/

As you know, the "Support Library 24" includes a new, applicable, and convenient class: Diffutil, which allows you to get rid of the boredom and error of cell changes and updates.

If you don't know it yet, you can read Nicola Despotoski's good article about it. This article explains how easy it is to handle it.

In fact, the Java language introduced many templates, and I decided to study how it was implemented with Kotlin.

Example

I created a small app (which can be downloaded on github) as an example, and it selects items from a list of 10 items for the next recycerview.

Thus, from one iteration to the next, some are shown, some disappear, and sometimes the whole is updated.

If you know how Recyclerview works, you know how the adapter notifies those changes, which requires these three methods:

    • Notifyitemchanged
    • notifyiteminserted
    • Notifyitemremoved

And the range changes they correspond to.

The Diffutil class will do all the calculations and invoke the required notify method.

Original Implementation method

For the first iteration, we get these items from the "provider," which allows the adapter to notify the change (which, if not the best code, can quickly understand why):

1 Private Fun Filladapter () {2     val olditems = adapter.items3     adapter.items =  Provider.generate ()4    adapter.notifychanges (OldItems, Adapter.items)5 }

Simple: I save the previous project, generate a new project, say notifychanges to the adapter, and use the Diffutil method is this:

1Fun Notifychanges (Old:list<content>,New: list<content>) {2Val diff =Diffutil.calculatediff (Object:DiffUtil.Callback () {3 Override Fun Areitemsthesame (Olditemposition:int, Newitemposition:int): Boolean {4             returnOld[olditemposition].id = =New[Newitemposition].id5         }6    7 Override Fun Arecontentsthesame (Olditemposition:int, Newitemposition:int): Boolean {8             returnOld[olditemposition] = =New[Newitemposition]9         }Ten  OneOverride Fun getoldlistsize () =old.size A         -Override Fun getnewlistsize () =New. Size -     }) the  -Diff.dispatchupdatesto ( This) -}

Since most of the code is based on templates, this is annoying, but it's going to be back later.

Now, as you can see, I called notifychanges after setting up a new set of items. Then why don't we entrust those acts?

Make notifications easier with delegates

If we know that every time a group of items is notified, then only Delegates.observer is needed, then the code is great:

This activity is very simple:

1 Private Fun Filladapter () {2     adapter.items = provider.generate ()3 }

The observer looks very good:

1 class Contentadapter ():recyclerview.adapter<contentadapter.viewholder>() {23     var Items:list<content> by delegates.observable (Emptylist ()) {4         new -5                  New)6    }7     ... 8 }

That's great! However, this can be even better.

Ability to boost adapters with extension functions

Most of Notitychanges's code is modeled. With data classes, we need to implement a method that determines whether two items are the same, even if their contents are different.

In this example, the identification method is the ID.

In this way, I create an extension function for this adapter that will do most of the hard work for us:

1Fun <T> recyclerview.adapter<*>.autonotify (old:list<t>,New: List<t>, compare: (T, T),Boolean) {2Val diff =Diffutil.calculatediff (Object:DiffUtil.Callback () {3 4 Override Fun Areitemsthesame (Olditemposition:int, Newitemposition:int): Boolean {5             returnCompare (Old[olditemposition],New[newitemposition])6         }7 8 Override Fun Arecontentsthesame (Olditemposition:int, Newitemposition:int): Boolean {9             returnOld[olditemposition] = =New[Newitemposition]Ten         } One  AOverride Fun getoldlistsize () =old.size -  -Override Fun getnewlistsize () =New. Size the     }) -  -Diff.dispatchupdatesto ( This) -}

This function receives two sets of items, and another function. This final parameter will be used in areitemsthesame to determine whether the two groups of items are the same.

Now the call is like this:

1 var items:list<content> by Delegates.observable (Emptylist ()) {2     new 3             new) {o, n-o.id = = N.id}4 }

Combined use

I can understand that you really don't like the solution in front of you. And in certain cases, you don't want all adapters to use it.

However, there is a replacement method: interface.

Sadly, in some locations on the Kotlin preview, the interface cannot extend the class (I would very much like to be able to add it in the future). This allows you to enforce the class implementation of the interface type using the method of the extension class.

However, we can also get similar results by moving the extension function inside the interface:

1 Interface Autoupdatableadapter {23     new: List<t>, compare: (T, T), Boolean) {4        ... 5     }6 }

The adapter only needs to implement this interface:

1 class Contentadapter (): Recyclerview.adapter<contentadapter.viewholder>(), Autoupdatableadapter {2     .... 3 }

That's all the code, and the rest stays the same.

Conclusion

There are several ways to use DIFFUTLS to make code look better and simpler than Java.

If you need to try another solution, get from the code base and remove some special comments.

Kotlin Secret recipe for Android (II): Recyclerview and Diffutil

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.