Sunday, September 21, 2014

Why themes are not taken into account when using custom ArrayAdapters..

While trying to implement basic extensions of ArrayAdapter with a ListView (see
https://github.com/thecodepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView), I noticed none of the themes that I used was being followed by the adapter:
   if (convertView == null) {
          convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false);
       }

It turns out that the use of getContext() matters a lot.  I found that if I used parent.getContext(), the styles do get applied.
   if (convertView == null) {
          convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false);
       }

Here is more background of why getContext() use matters..

http://www.doubleencore.com/2013/06/context/

The less obvious issue is inflating layouts. If you read my last piece on layout inflation, you already know that it can be a slightly mysterious process with some hidden behaviors; using the right Context is linked to another one of those behaviors. While the framework will not complain and will return a perfectly good view hierarchy from a LayoutInflater created with the application context, the themes and styles from your app will not be considered in the process. This is because Activity is the only Context on which the themes defined in your manifest are actually attached. Any other instance will use the system default theme to inflate your views, leading to a display output you probably didn’t expect.