Skip to content

ListView

Paweł Pastuszak edited this page Feb 13, 2016 · 11 revisions

This article applies to VisUI 1.0.0

ListView (source) allows to create advanced lists. ListView is powerful and flexible, items views are created using list adapter which allows to huge view customization. List item selection can be enabled, it allows to both single and multiple selection mode. List is scrollable, you can specify custom table header and footer. Items can be sorted using supplied comparator.

Creating ListView

SimpleListAdapater<Model> adapter = new SimpleListAdapter<Model>(array);
ListView<Model> view = new ListView<Model>(adapter);
table.add(view.getMainTable()).grow();

Creating ListView requires to pass instance of ListAdapter which is responsible for creating views to array items. In this case we pass SimpleListAdapter instance which uses toString() to create item view. Adapters also provide methods to manipulate collection elements such as add, remove etc. Those methods should always be used when manipulating collection displayed by ListView because they will automatically update ListView. If array was modified directly adapter.itemsChanged() must be called before user interacts with ListView.

ItemClickListener

If you want to get notified when user has clicked an view you can set ItemClickListener for ListView:

listView.setItemClickListener(new ItemClickListener<Model>() {
	@Override
	public void clicked (Model item) {
		System.out.println("Clicked: " + item.name);
	}
});

Creating custom adapter

Creating custom adapter will give you option to customize how ListView displays array items. Instead of implementing ListAdapter directly your adapter class should extend ArrayAdapter (if you are using libGDX's Array class) or ArrayListAdapter (if you are using ArrayList). If you want to implement adapter for custom collection extend AbstractListAdapter and see ArrayAdapter or ArrayListAdapter for example how to do so.

In this simple adapter for Array we create VisLabel to display String content.

private static class ExampleAdapter extends ArrayAdapter<String, VisTable> {
	public ExampleAdapter (Array<String> array) {
		super(array);
	}

	@Override
	protected VisTable createView (String item) {
		VisLabel label = new VisLabel(item);

		VisTable table = new VisTable();
		table.left();
		table.add(label);
		return table;
	}
}

ArrayAdapater is a generic type, first type is item type that will be stored and the second one is the type of view.

String is immutable but your items may need updating, in that case you can additionally override updateView:

	@Override
	protected void updateView (VisTable view, String item) {
		//update your view here...
	}

Note that you need to notify adapter that items data has changed by calling adapter.itemsDataChanged()

Items selection

Adapater extends AbstractListAdapater allows to enable items selection. This requires setting selection mode and overriding selectView and deselectView.

private static class ExampleAdapter extends ArrayAdapter<String, VisTable> {
	public ExampleAdapter (Array<String> array) {
		super(array);
		setSelectionMode(SelectionMode.SINGLE);
	}

	@Override
	protected void selectView (VisTable view) {
	}

	@Override
	protected void deselectView (VisTable view) {
	}

	//remainder omitted
}

The role of selectView and deselectView is to update your view when it was selected and deselected. Most of the time you would want to highlight it so user can see it's selected:

private static class ExampleAdapter extends ArrayAdapter<String, VisTable> {
	//consider creating Style class, see SimpleListAdapter source for example
	private final Drawable bg = VisUI.getSkin().getDrawable("window-bg");
	private final Drawable selection = VisUI.getSkin().getDrawable("list-selection");

	public ExampleAdapter (Array<String> array) {
		super(array);
		setSelectionMode(SelectionMode.SINGLE);
	}

	@Override
	protected void selectView (VisTable view) {
		view.setBackground(selection);
	}

	@Override
	protected void deselectView (VisTable view) {
		view.setBackground(bg);
	}

	//remainder omitted
}

That's all needed to enable selection, you can also allow multiple items selection by calling setSelectionMode(SelectionMode.MULTIPLE); to get selected items call adapter.getSelection(), returned array must not be modified.

Other functions

Sorting items

You can also specify comparator that will be used to sort items:

//should be called inside your adapter constructor
setItemsSorter(new Comparator<String>() {
	@Override
	public int compare (String o1, String o2) {
		return o1.toLowerCase().compareTo(o2.toLowerCase());
	}
});

Note that this will sort and change order of items in underlying collection.

View header and footer

You can specify custom elements that will be displayed at the top or bottom of the table. There are two methods: listView.setHeader(Actor) and listView.setFooter(Actor). For example:

VisTable footerTable = new VisTable();
footerTable.addSeparator();
footerTable.add("Table Footer");
view.setFooter(footerTable);

View UpdatePolicy

By default views are updated right after data was invalidated, this behavior may be changed by setting ListView update policy, if you want to only update views before ListView is drawn call:

view.setUpdatePolicy(UpdatePolicy.ON_DRAW);