RecyclerView
里面有个楼层使用 android.support.design.widget.TabLayout
作一个 Tab 切使用:android
RecyclerView.Adapter
里OnCreateViewHolder
简单返回一个ViewHolder
:安全
return new ViewHolder(LayoutInflater
.from(applicationContext).inflate(R.layout.xx, parent, false))
复制代码
这里我使用的是ApplicationContext
,由于我一直被教导不要持有activity
的引用,so都是Context
应该没有什么不一样。bash
到楼层展现的时候报错:app
android.view.InflateException:
Binary XML file line #7:
Error inflating class android.support.design.widget.TabLayout
复制代码
最早确定是检查 xml 文件里面的类路径是否正确,检查后发现没问题。post
问题报错解析 TabLayout 类的时出错,打断点,发如今该行代码时崩溃(TabLayout代码在不一样版本里相关代码位置会发生微调,本场景是design.28.0.0
版本):ui
public TabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
......
TypedArray a = ThemeEnforcement.obtainStyledAttributes(...);
......
}
复制代码
继续深刻:this
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);
.....
}
复制代码
继续深刻:spa
private static void checkCompatibleTheme(Context context, AttributeSet set, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
......
checkAppCompatTheme(context);
}
复制代码
继续深刻:code
public static void checkAppCompatTheme(Context context) {
checkTheme(context, APPCOMPAT_CHECK_ATTRS, "Theme.AppCompat");
}
复制代码
问题代码找到:component
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).");
}
}
复制代码
跟主题没找到有关。
咱们在使用继承该 Activity 时必须使用 Theme.Appcompat 及其子类的主题,否则也会报这个错误。基本问题缘由能够定位为LayoutInflater
没有带 theme 去解析。
Look at here:LayoutInflater.from参数Context传Activity、Application区别
归根结底是我传入的是 ApplicationContext
,解析时没有带 theme
致使崩溃。
一直认为 LayoutInflater.from() 传入应用上下文一劳永逸且安全,在大多数场景下没有问题,能够成功解析,可是对于有 theme 要求的控件,仍是须要使用 activity 传入解析。