Skip to content

ListView

Pawel Pastuszak edited this page Dec 7, 2018 · 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 for huge view customization. List's items selection can be enabled, either in single or multiple selection mode. List is scrollable, you can specify custom table header and footer. Items can be sorted using supplied comparator.

Creating ListView

SimpleListAdapter<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 for 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 is stored in collection and the second one is the type of view.

String is immutable so views never need updating but your items might be mutable, 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

All adapters extending AbstractListAdapater allows for enabling items selection. This requires setting selection mode and overriding selectView and deselectView methods.

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 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);