4

It occurred to me while using AppCompat, that I had been using things like Button instead of android.support.v7.widget.AppCompatButton within my layout XML files. I did a test, via view.getClass().getSimpleName() and confirmed that even though I declared it as a Button in the XML, the class being loaded was in fact AppCompatButton.

How does this work, under the hood?

BLuFeNiX
  • 2,496
  • 2
  • 20
  • 40

1 Answers1

7

In the process of researching this topic in order to ask the question correctly, I discovered the answer myself.

When using AppCompatActivity, some interesting things happen:

  1. A LayoutInflater.Factory is applied to the default LayoutInflater, via setFactory. The AppDelegateImpl classes within AppCompat implement the Factory interface, and one of them is chosen as the factory delegate depending on the API level. There is also a slightly different Factory2, targeting later APIs.
  2. When your views are being inflated from XML, the name of the view's class is passed into the Factory's createView method, which is given the opportunity to override the actual view that is created.
  3. The name of the view is checked against a hard-coded hash table of strings in AppCompatViewInflater, and if a match is found the view is inflated by the delegate, instead of the default inflater.
BLuFeNiX
  • 2,496
  • 2
  • 20
  • 40
  • 2
    You can even override the inflater in your theme. AppCompat has this: `androidx.appcompat.app.AppCompatViewInflater`. MaterialComponents theme uses this to inject its own custom layout inflater. At least since support library 28, don't know how it worked before. – Eugen Pechanec Feb 07 '19 at 17:01
  • What if you wish to do it manually (example is when you inflate something and notice that the library isn't being used) ? Or even wrap what's of the library? – android developer Sep 30 '21 at 11:28