Update 4/17/15: I had originally wrongly assumed that AppCompat tinting did not work with LayoutInflater.from(context). That’s what I get for not testing my assumptions!

LayoutInflater is a fundamental component in Android. You must use it all the time to turn xml files into view hierarchies. There are several ways to get an instance of one, but it’s not always clear why you should prefer one way over another.

Perhaps the must fundamental way to obtain a LayoutInflater is with

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)

which gets you a LayoutInflater directly from the system service, though it is a bit verbose.

An easier way to accomplish the same thing is with

LayoutInflater layoutInflater = LayoutInflater.from(context)

which is just a simple wrapper around the above.

If you are using AppCompat, you may be wondering how they manged to implement view tinting. To answer this, we must take a short detour into a very cool feature of LayoutInflaters: custom factories.

LayoutInflater provides a couple of methods that allow you to customize layout inflation setFactory(LayoutInflater.Factory factory) and setFactory2(LayoutInflater.Factory2 factory). The second one is just an update to the factory interface added in API 11. If you are targeting 11+ you should use Factory2. Otherwise, you should use the original Factory.

The layout factory provides the method

View onCreateView(String name, Context context, AttributeSet attrs)

(or for Factory2)

View onCreateView(View parent, String name, Context context, AttributeSet attrs)

for you to override. With this, you can customize what view gets created for what tag however you want. To trigger the default behavior, just return null.

Note that you can only set one factory on the LayoutInflater. This may seem limiting, but you can get around this limitation by cloning the inflater and then setting the factory on the result.

LayoutInlater newLayoutInlflater = layoutInflater.cloneInContext(context);
newLayoutInflater.setFactory(myNewFactory);

The new LayoutInflater will merge the two factories, applying your new one first. If it returns null, it will apply the original one, before falling back to the default implementation.

All LayoutInflaters have a default Factory set on them, your Activity. Activity actually implements LayoutInflater.Factory and LayoutInflater.Factory2. The LayoutInflater returned using that Activity as a Context sets the factory to that Activity for you. That way, you can customize the inflater easily by just overriding onCreateView() right in the Activity.

So what does this have to do with AppCompat tinting? Well, ActionBarActivity overrides these methods to replace views with their tinted AppCompat versions. Therefore, if you want to get this replacement you must obtain the LayoutInflater with the ActionBarActivity as the context.

The final way to get an instance of LayoutInflater, is from the method onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) in a Fragment. This just passes in the result of Activity.getLayoutInflater(), so everything above applies. Well, almost everything – support fragments and Lollipop actually set their own factory so that tags are correctly added to the child fragment manager instead of the parent one.