2015-10-29 1 views
16

При накачивании моего макета, я получаю это исключение:android.view.InflateException при использовании selectableItemBackground

E AndroidRuntime: android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class <unknown> 
E AndroidRuntime:  at android.view.LayoutInflater.inflate(LayoutInflater.java:539) 
E AndroidRuntime:  at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
E AndroidRuntime:  at com.myapp.view.MyRecyclerAdapter.onCreateViewHolder(MyRecyclerAdapter:80) 
E AndroidRuntime:  at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:5288) 
E AndroidRuntime:  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4551) 
E AndroidRuntime:  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4461) 
E AndroidRuntime:  at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1962) 

Там нет «Вызванный» в журнале, но я добавил код, чтобы поймать исключение и вызвать getCause() пока он не возвращает нуль, а вот последовательность событий:

android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class <unknown> 
android.view.InflateException: Binary XML file line #11: Error inflating class <unknown> 
Error: Binary XML file line #11: Error inflating class <unknown> 
android.content.res.Resources$NotFoundException: File res/drawable-v11/selectable_list_background.xml from drawable resource ID #0x7f020096 
java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0100f9 a=-1} 

0x7f020096 является selectable_list_background (см ниже), а TypedValue он ссылается является ?selectableItemBackground.

Я сузил исключение до моего использования ?selectableItemBackground. Более конкретно, я использую CardView:

<android.support.v7.widget.CardView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:foreground="@drawable/selectable_list_background" 
    card_view:cardCornerRadius="4dp" 
    card_view:cardElevation="4dp" 
    > 

И это соответствующую часть drawable/selectable_list_background:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="?selectableItemBackground" /> 
</selector> 

Эта деятельность использует свою собственную тему, его родитель Theme.AppCompat.Light.NoActionBar.

Этот код работал, но я просто выкопал этот код через несколько месяцев, и теперь он сбой исключается. Я предполагаю, что это связано с обновлением библиотеки поддержки до 23.0.1 и целевым SDK до 23, но я еще не вернулся к 22, чтобы убедиться в этом.

Все работает нормально, если я удаляю одну строку, ссылающуюся на ?selectableItemBackground. Я также пробовал ?attr/selectableItemBackground и ?android:attr/selectableItemBackground, но получил те же результаты. (Последнее заставляет меня поверить, что это может быть не проблема с библиотекой поддержки).

EDIT:

Я смотрел на него в отладчике, и у меня есть подозрение, что этот код в android.content.res.Resources, внутри loadDrawable():

Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException { 
    [...] 
    dr = loadDrawableForCookie(value, id, null); 

Обратите внимание, что эта функция принимает тему , но не передает его при вызове loadDrawableForCookie(), который является методом, который в конечном итоге вызывает первое исключение:

java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0100f9 a=-1} 
    at android.content.res.TypedArray.getDrawable(TypedArray.java:867) 
    at android.graphics.drawable.StateListDrawable.inflateChildElements(StateListDrawable.java:170) 
    at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:115) 
    at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:1215) 
    at android.graphics.drawable.Drawable.createFromXml(Drawable.java:1124) 
    at android.content.res.Resources.loadDrawableForCookie(Resources.java:2630) 
    at android.content.res.Resources.loadDrawable(Resources.java:2540) 
    at android.content.res.TypedArray.getDrawable(TypedArray.java:870) 
    at android.view.View.<init>(View.java:4280) 

Этот код кажется новым для Android 6.0 - код 5.0 совсем другой, но тема передается при загрузке drawable. И тема необходима AFAICT - этот атрибут является частью AppCompat, поэтому для его решения нужна тема деятельности.

Это похоже на вопиющую ошибку, поэтому я не уверен, что я на правильном пути здесь. Есть идеи?

+0

Какая родительская тема вы использовали для AppTheme? –

+0

@FabinPaul Извините, я должен был упомянуть об этом. Родительская тема - 'Theme.AppCompat.Light.NoActionBar'. – EboMike

+0

Пробовал ли вы использовать родительскую тему Base.V7.Theme.AppCompat.Light –

ответ

5

Официальный ответ - вы не можете использовать атрибуты темы для атрибутов android:drawable или android:src. Просто невозможно, по дизайну. Есть еще один ответ, который исследует ту же проблему и предлагает решение: How to reference style attributes from a drawable?

В моем случае я не мог этого сделать, так как от AppCompat ссылается на личную вытачку. Поэтому я выбрал решение для кода. Я устанавливаю передний план на ?selectableItemBackground, пока карта не выбрана, и в мой собственный список состояний, который можно извлечь, когда я в режиме выбора.

Это очень уродливое решение, настолько уродливое, что я не собираюсь делиться этим кодом здесь, но лучше всего я могу придумать до сих пор. Если у кого-то есть лучшее решение, я бы хотел это услышать.

+5

Вы уверены, что использовали свою 'Активность' как 'Context' для раздувания, а не' ApplicationContext'? – artkoenig

+0

Спасибо! Неправильный контекст может быть причиной неудачи – andre719mv

+0

@ ArtjomKönig Вы спасли мой день. – wonsuc

3

Как @Artjom говорит, что проблема заключается в прохождении application context при создании пользовательского вида. Я также столкнулся с тем же вопросом, и я проходил getApplicationContext() вместо activity как context. После прохождения Activity как проблема context проблема решена.

Надеюсь, это может помочь кому-то еще.