Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android.view.InflateException when using selectableItemBackground

When inflating my layout, I get this exception:

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)

There is no "Caused by" in the log, but I added code to catch the exception and call getCause() until it returns null, and here is the sequence of events:

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 is selectable_list_background (see below), and the TypedValue it references is ?selectableItemBackground.

I narrowed the exception down to my use of ?selectableItemBackground. More specifically, I'm using a 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"
    >

And this the relevant part of 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>

This activity is using my own theme, its parent is Theme.AppCompat.Light.NoActionBar.

This code used to work, but I just dug up this code after a few months, and now it crashes with the exception. My guess is that this is related to upgrading the support library to 23.0.1 and target SDK to 23, but I haven't switched back to 22 yet to verify that.

It all works fine if I remove the one line referencing ?selectableItemBackground. I also tried ?attr/selectableItemBackground and ?android:attr/selectableItemBackground, but got the same results. (The latter makes me believe that it may not be a problem with the support library).

EDIT:

I looked at it in the debugger, and I have a suspicion that it is this code in android.content.res.Resources, inside loadDrawable():

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

Note that this function takes a theme, but doesn't pass it in when calling loadDrawableForCookie(), which is the method that eventually triggers the first exception:

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)

This code seems to be new to Android 6.0 - the 5.0 code is quite different, but the theme is passed in when loading the drawable. And the theme is necessary AFAICT - the attribute in question is part of AppCompat, so it needs the activity's theme to resolve it.

That seems like a blatant bug though, so I'm not convinced that I'm on the right track here. Any ideas?

like image 584
EboMike Avatar asked Oct 29 '15 08:10

EboMike


4 Answers

As @Artjom says problem is with passing application context while creating custom view. I was also facing the same issue and I was passing getApplicationContext() instead of the activity as context. After passing Activity as a context problem resolved.

Hope it might help to someone else.

like image 119
Smeet Avatar answered Nov 20 '22 03:11

Smeet


The official answer - you can't use theme attributes for android:drawable or android:src attributes. Simply not possible, by design. There's another answer that explores the same issue and offers a solution: How to reference style attributes from a drawable?

In my case, I couldn't really do that since AppCompat's ?selectableItemBackground references a private drawable. So I opted for a code solution - I'm setting the foreground to ?selectableItemBackground while the card is not selected, and to my own state list drawable once I'm in selection mode.

This is a very ugly solution, so ugly that I'm not going to share the code here, but the best I could come up with so far. If somebody has a better solution, I'd love to hear it.

like image 40
EboMike Avatar answered Nov 20 '22 01:11

EboMike


Unfortunately, other answers are not my case. The way to work for me is to check if your activity uses AppCompat theme style:

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>

Then use AppCompat theme in your activity (in many ways, but I show the way to use Manifest):

<application
        android:name=".Abbott"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    <!-- Any configuration inside -->

</application>
like image 1
Nguyen Tan Dat Avatar answered Nov 20 '22 02:11

Nguyen Tan Dat


I had the same error when using the androidx Fragment Testing component. By default launchFragmentInContainer() uses the theme FragmentScenarioEmptyFragmentActivityTheme, resulting in the error.

Simple fix is to use your own theme which extends AppCompat:

launchFragmentInContainer(theme = R.style.AppTheme)

like image 1
nmw Avatar answered Nov 20 '22 01:11

nmw