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 傳入解析。