In the last tutorial, we talk about how we can bind to ArrayList of String. We can actually do very little thing with String, and in this tutorial, we are going to show how we can bind to a list of View Models, that we can display and invoke command to modify their states.

Series Directory:

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

Once again, let me remind, this tutorial’s code is coming from the AndroidBindingMarkupDemo which is available in the project repository. If you are interested in seeing the thing in action, you can grab the demo from Android Market (search AndroidBinding or Andy Tsui).

Since we are going to bind to View Models, we have to define our View Model Class:

public class ArrayListItem{
private static final String Prefix = "Item: ClickCount=";
public final Command ClickTitle = new Command(){
public void Invoke(View view, Object... args) {
ClickCount.set(ClickCount.get()+1);
}
};

public final IntegerObservable ClickCount = new IntegerObservable(0);
public final DependentObservable<String> Title = new DependentObservable<String>(String.class, ClickCount){
@Override
public String calculateValue(Object... args) throws Exception {
return Prefix + ClickCount.get();
}
};
}

The above View Model looks exactly the same as other View Models. We can have Observables, Dependents and even Commands. We can expect whenever the ClickTitle Command is invoked, the Title will be updated too.

Then, in the “Master” View Model, we just need:


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


Same as binding to list of String, we just need to tell what the class is your Child View Model is, and Android Binding is capable to handle the rest. So, what about the View? Following is the List View Declaration:


<ListView
android:id="@+id/lvItems"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
binding:itemSource="Items"
binding:itemTemplate="@layout/arraylist_item"
/>


Which isn’t any interesting point to talk about, and the item template (arraylist_item.xml):


<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:binding="http://www.gueei.com/android-binding/"
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingLeft="6dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
binding:text="Title"
binding:onClick="ClickTitle"
/>

We are now binding the text to “Title” property and also the onClick event to “ClickTitle” Command.

One more thing before we move on to Cursor (which will be in next tutorial), ArrayListObservable items can be dynamically add, change or remove, and the changes will be automatically reflected in the User Interface. The subscription interface is a little bit different than Observable (which is subscribe to Observer), in contrast, CollectionObservables subscribes to CollectionObserver. If you look at the demo source code, you may find the following codes:


public final Command AddItem = new Command(){
@Override
public void Invoke(View view, Object... args) {
Items.add(new ArrayListItem());
}
};

public final Command RemoveItem = new Command(){
@Override
public void Invoke(View view, Object... args) {
if (Items.size()>0)
Items.remove(Items.size() - 1);
}
};

And whenever the above two Commands are invoked, the ListView will change accordingly.