This is the  last post in this series, which is about lazy loading. Note this lazy loading is different from the lazy loading on the other infinite list post. Which, for infinite list, you don’t yet know how many items will be on your list, you just load them bit by bit whenever necessary; but for the lazy loading here, you know what and how many items here, but you don’t load “partial” of the content until it is necessary.

The most common scenario is a list of images, either coming from local disk or the Internet. Setting Image to Image View is a quite expensive operation, even you already cached the image in local drive. People love to fast scroll to skim a list, and this makes list very unresponsive if the image is loaded even in fast scrolling mode.

Kindly note this is the last post of this series, where the rest are:

  1. Introduction to List Views Binding
  2. Custom Row Model for List View
  3. Binding to Cursors
  4. Lazy Loading (this)

In the Android’s official API Demo, it also showcased such functionality, which is called Slow List (Under API Demo > Views > Lists). Since lazy loading is about loading stuff that is visible to users. There we have two possible scenarios:

  1. Load when scrolling
  2. Load the (expensive) content only when scrolling stopped

First one is pretty much default behavior of most lists, but we still have a problem of how and when to cache those contents, if fetching them is expensive (like, getting from Internet). Second one is demoed in the above mentioned API Demo. How we going to implement it in Android Binding as we are not directly touching onScroll events normally?

For the layout part, it is no different from other kinds of lists, so we just skip it and look at the View Model:

    public final ArrayListObservable<LazyObject> Items =
        new ArrayListObservable<LazyObject>(LazyObject.class);

    public class LazyObject implements LazyLoadRowModel{
        public final StringObservable Title = new StringObservable("loading...");

        @Override
        public void display(IObservableCollection<?> collection, int index) {
            Title.set(DATA[index]);
        }

        @Override
        public void hide(IObservableCollection<?> collection, int index) {
            Title.set("loading...");
        }
    }

Once again, let me remind you the above code is extracted from the Markup Demo.

Lazy Load Row Model

LazyLoadRowModel is an interface with two methods: display and hide. Normally, you only need to supply a plain object to ArrayListObservable, but with LazyLoad interface, you can control when you want to load the data, and if necessary, dispose it in hide(). However, the display() is not guaranteed to be called only once, even that particular item has never disappear from the screen, so, if expensive operation needed to call from that one, you need to implement your own detection and cache if necessary.

How about Cursors?

In most cases, your cursor’s row should inherit from RowModel, and you only need to override the onDisplay() and onHide() methods for Lazy Loading.

Advertisements