Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ListView tips and tricks

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →
Avatar for Tibi Giurgiu Tibi Giurgiu
September 13, 2012

ListView tips and tricks

Avatar for Tibi Giurgiu

Tibi Giurgiu

September 13, 2012

Other Decks in Programming

Transcript

  1. Overview • a view group that displays a list of

    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
  2. Virtualization • Problem: large data sets – Memory – Performance

    • Solution – Populate on demand – Recycle views to reduce object churn
  3. • DOs – use the recycled view – ok to

    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()
  4. Multiple Item Types • int getItemViewType(int position) – type of

    View for a given position – used to provide the right convertView • getViewTypeCount() – how many types to expect – must remain constant
  5. Handling dataset changes • notifyDataSetChanged() – new or updated data

    – 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
  6. Handling emptiness • AdapterView.setEmptyView(View emptyView) – AdapterView hides/displays it according

    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
  7. Transcript and stack from bottom • android:transcriptMode – behavior of

    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
  8. Headers and Footers • ListView.addHeaderView() • ListView.addFooterView() • Must be

    called before setAdapter() • list.getAdapter() returns a android.widget.HeaderViewListAdapter
  9. Don't: android:layout_height="wrap_content" • getView() called too many times • forces

    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
  10. Add clickable areas • ListView blocks clicks of itemview containing

    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.
  11. Lazy loading images • the view you’re loading the image

    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
  12. private static class ThumbnailTask extends AsyncTask<Void, Void, Bitmap> { private

    int mPosition; private ViewHolder mHolder; public ThumbnailTask(int position, ViewHolder holder) { mPosition = position; mHolder = holder; } @Override protected Bitmap doInBackground(Void... arg0) { // Download bitmap here } @Override protected void onPostExecute(Bitmap bitmap) { if (mHolder.position == mPosition) { mHolder.thumbnail.setImageBitmap(bitmap); } } }
  13. public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState ==

    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
  14. Clasic Lazy loading pattern public View getView(int position, View convertView,

    ViewGroup parent) { // ... setupView Bitmap image = loadImageFromCache(url); if (image != null) { imageView.setImageBitmap(image); } else { AsyncTask loadImageTask = new AsyncTask<Void, Void, Bitmap>() { protected Bitmap doInBackground(Void... params) { return loadImageFromNetwork(url); } protected void onPostExecute(Bitmap image) { if (image != null && imageView.getTag().equals(url)) { imageView.setImageBitmap(image); } } }; // ... setup no image loaded view imageView.setTag(url); loadImageTask.execute(); } }
  15. Better solution public View getView(int position, View convertView, ViewGroup parent)

    { // ... setupView Bitmap image = loadImageFromCache(url); if (image != null) { imageView.setImageBitmap(image); } else { AsyncTask loadImageTask = new AsyncTask<Void, Void, Bitmap>() { protected Bitmap doInBackground(Void... params) { return loadImageFromNetwork(url); } protected void onPostExecute(Bitmap image) { if (image != null && imageView.getTag().equals(url)) { adapter.notifyDataSetChanged(); } } }; // ... setup no image loaded view imageView.setTag(url); loadImageTask.execute(); } }
  16. • Android Developers https://developer.android.com/guide/topics/ui/layout/listview.html • Google IO 10, The world

    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