AppCompat 如何扩展未明确使用 AppCompat 小部件的布局?

How does AppCompat inflate layouts that do not explicitly use AppCompat widgets?

我在使用 AppCompat 时突然想到,我在布局 XML 文件中使用了 Button 而不是 android.support.v7.widget.AppCompatButton 之类的东西。我通过 view.getClass().getSimpleName() 进行了测试,并确认即使我在 XML 中将其声明为 Button,加载的 class 实际上是 AppCompatButton .

这是如何工作的?

为了正确提出问题而研究这个话题的过程中,我自己发现了答案。

使用 AppCompatActivity 时,会发生一些有趣的事情:

  1. A LayoutInflater.Factory 通过 setFactory 应用于默认值 LayoutInflater。 AppCompat 中的 AppDelegateImpl classes 实现了 Factory 接口,并且根据 API 级别选择其中之一作为工厂委托。还有一个略有不同的 Factory2,目标稍后 APIs.
  2. 当您的视图从 XML 膨胀时,视图的 class 的名称被传递到 FactorycreateView 方法中,该方法被赋予有机会覆盖创建的实际视图。
  3. 根据 AppCompatViewInflater 中字符串的硬编码散列 table 检查视图的名称,如果找到匹配项,视图将由委托而不是默认值扩充充气机。