scrollable items • designed for scalability and performance • an Adapter pulls content from a source and converts each item result into a view that's placed into the list. java.lang.Object ↳ android.view.View ↳ android.view.ViewGroup ↳ android.widget.AdapterView<T extends android.widget.Adapter> ↳ android.widget.AbsListView ↳ android.widget.ListView
use drawable resources (cached internally) • DON'Ts – perform long operations (network, db, sharedPrefs, files, bitmaps etc.) – call findViewById() if not necessary => ViewHolder pattern – change convertView structure (use view type system for this instead) getView()
– list view rescans the adapter for the views on screen – MUST be called everytime you change your adapter – commit adapter changes on the UI thread, call notifyDataSetChanged() in the same UI event • notifyDataSetInvalidated() – no more data available
to the adapter state – the AdapterView and the empty view are mutually exclusive in term of visibility • ListActivity/ListFragment makes it easier – id for the ListView: android.R.id.list – id for the empty view: android.R.id.empty
the list when the content changes – “disabled”, doesn’t scroll – “normal”, scrolls to the bottom if last item is visible – “alwaysScroll”, always scrolls to the bottom • android:stackFromBottom – stack items in reverse order – starts with the last item from the adapter
ListView to measure a few children at layout time, to know how big it should be • Solution: – android:layout_height="fill_parent" :) – inside LinearLayout, android:layout_height="0dp" and use layout_weight
at least one focusable descendant – Solution: • android:focusable="false" on all controls • set android:descendantFocusability="blocksDescendants" for the root • Android, by default, recursively dispatches the pressed state of a ViewGroup to all of its children – Solution: don’t ‘accept’ the pressed state when the parent is already in the pressed state.
for might be recycled before the async operation finishes • attach some piece of information to the view that identifies which row is associated with it
OnScrollListener.SCROLL_STATE_FLING) { mPhotoLoader.pause(); } else if (mDisplayPhotos) { mPhotoLoader.resume(); } } • start an asynchronous operation on every getView() call while scrolling => most of the results would be discarded • setOnScrollListener(), don't load if SCROLL_STATE_FLING
of ListView http://www.google.com/events/io/2010/sessions/world-of-listview-android.html • Cyril Motier, Android Dev Blog http://android.cyrilmottier.com • Lucas Rocha, Performance Tips for Android’s ListView http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ • Janusz Leidgens, Lazy Loading in Lists http://journeyman.janusz.de/ References