一、复现
1.1. 场景
RecyclerView
里面有个楼层使用 android.support.design.widget.TabLayout
做一个 Tab 切使用:

1.2 问题代码出处
RecyclerView.Adapter
里OnCreateViewHolder
简单返回一个ViewHolder
:
return new ViewHolder(LayoutInflater
.from(applicationContext).inflate(R.layout.xx, parent, false))
这里我使用的是ApplicationContext
,因为我一直被教导不要持有activity
的引用,so都是Context
应该没有什么不同。
1.3 报错
到楼层展示的时候报错:
android.view.InflateException:
Binary XML file line #7:
Error inflating class android.support.design.widget.TabLayout
二、查找问题代码
2.1 XML 检查
最先肯定是检查 xml 文件里面的类路径是否正确,检查后发现没问题。
2.2 代码分析
问题报错解析 TabLayout 类的时出错,打断点,发现在该行代码时崩溃(TabLayout代码在不同版本里相关代码位置会发生微调,本场景是design.28.0.0
版本):
public TabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
......
TypedArray a = ThemeEnforcement.obtainStyledAttributes(...);
......
}
继续深入:
public static TypedArray obtainStyledAttributes(Context context, AttributeSet set, @StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes, @StyleableRes int... textAppearanceResIndices) {
checkCompatibleTheme(context, set, defStyleAttr, defStyleRes);
.....
}
继续深入:
private static void checkCompatibleTheme(Context context, AttributeSet set, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
......
checkAppCompatTheme(context);
}
继续深入:
public static void checkAppCompatTheme(Context context) {
checkTheme(context, APPCOMPAT_CHECK_ATTRS, "Theme.AppCompat");
}
问题代码找到:
private static void checkTheme(Context context, int[] themeAttributes, String themeName) {
if (!isTheme(context, themeAttributes)) {
throw new IllegalArgumentException("The style on this component requires your app theme to be " + themeName + " (or a descendant).");
}
}
跟主题没找到有关。
三. 分析
1. AppcompatActivity
我们在使用继承该 Activity 时必须使用 Theme.Appcompat 及其子类的主题,不然也会报这个错误。基本问题原因可以定位为LayoutInflater
没有带 theme 去解析。
2. Activity Context 与 Application Context 区别
Look at here:LayoutInflater.from参数Context传Activity、Application区别
归根结底是我传入的是 ApplicationContext
,解析时没有带 theme
导致崩溃。
四、总结
一直认为 LayoutInflater.from() 传入应用上下文一劳永逸且安全,在大多数场景下没有问题,可以成功解析,但是对于有 theme 要求的控件,还是需要使用 activity 传入解析。