0

today, I have encountered this problem: I am trying to use a custom TabLayout inside a RecyclerView item. Note that this same component has been used in other parts of the app without issue (never in RecyclerView tho).

The item I am trying to inflate only contains the TabLayout:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <my.package.CustomTabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent">

            <android.support.design.widget.TabItem
                android:id="@+id/tab1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/text1" />

            <android.support.design.widget.TabItem
                android:id="@+id/tab2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/text2" />

        </my.package.CustomTabLayout>

    </android.support.constraint.ConstraintLayout>

</layout>

the exception:

 android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class <unknown>
    Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
    Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.view.LayoutInflater.createView(LayoutInflater.java:647)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:126)
        at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)
        at my.package.recycler.MyAdapter.onCreateViewHolder(MyAdapter.kt:25)
        at my.package.recycler.MyAdapter.onCreateViewHolder.onCreateViewHolder(MyAdapter.kt:16)
[...]
Caused by: java.lang.IllegalArgumentException: You need to use a Theme.AppCompat theme (or descendant) with the design library.
        at android.support.design.widget.ThemeUtils.checkAppCompatTheme(ThemeUtils.java:33)
        at android.support.design.widget.TabLayout.<init>(TabLayout.java:298)
        at android.support.design.widget.TabLayout.<init>(TabLayout.java:292)
        at my.package.CustomTabLayout.<init>(CustomTabLayout.java:23)

in the adatper I am basically doing this: (can't show the whole code)

DataBindingUtil.inflate(LayoutInflater.from(MyApplication.getContext()), R.layout.tabs_item, parent, false)

there are other inflations in the the adapter, all working correctly.

I can't understand why it's working if used in activity directly but not in RecyclerView

Any idea?

jack_the_beast
  • 1,838
  • 4
  • 34
  • 67
  • 1
    Which `Context` is the `LayoutInflater` using? Presumably, the one you passed into `MyAdapter`. – Mike M. Nov 18 '19 at 16:26
  • Show us your app theme. Very likely you are using material theme, and trying to use old compat with it. – ror Nov 18 '19 at 16:27
  • @MikeM. I'm using the application context, I've updated the question – jack_the_beast Nov 18 '19 at 16:39
  • @jack_the_beast simply set another theme in the `AndroidManifest.xml`. – Martin Zeitler Nov 18 '19 at 16:40
  • @MartinZeitler I can post it but it's wuite useless as the only thing it does is using a different font and it's already working in other places with the exact same configuration as I posted – jack_the_beast Nov 18 '19 at 16:40
  • 1
    You cannot use the application `Context` there. It doesn't have a theme set on it (even though you may have specified an `android:theme` on the `` element). Use the current `Activity` instead. Or, if you really, really don't want to do that, for some reason, you could create a `ContextThemeWrapper` to pass to the `LayoutInflater` – e.g., `ContextThemeWrapper ctw = new ContextThemeWrapper(MyApplication.getContext(), R.style.WhateverAppTheme)` – but that's kinda silly, if you have an appropriately-themed `Activity` readily available. – Mike M. Nov 18 '19 at 16:41
  • @MikeM. that worked :) please post it as an answer, so I can accept it. Still don't understand why it worked with the other views I have – jack_the_beast Nov 18 '19 at 16:47
  • 1
    @jack_the_beast this question is closed already. And one can also inherit from such theme in `styles.xml`, by setting the `parent` theme accordingly (so that you can add custom styles for that custom tab-layout). – Martin Zeitler Nov 18 '19 at 16:48
  • 1
    Oop, he sneaked it! Oh, well. I'm sure I've probably done that to Martin before, at least once. Anyhoo, for further explanation, only certain library `View`s require specific themes. The other `View`s inflated in the `Adapter` apparently aren't any of those that do. And when you were in the `Activity`, it obviously had the right theme already, as that's basically what themes are for; the Activities, and all of the UI components it handles. As for the application, it's not going to have a theme on it, by default. That `theme` attribute simply serves to set a default theme for the Activities. – Mike M. Nov 18 '19 at 17:01
  • 1
    @MikeM. Likely the class which the `CustomTabLayout` extends requires it... and that `Application` by it self has no theme should be obvious, since it has no views at all. Likely the manifest-merger would even use that default value and apply it to the activities, which have nothing else defined. – Martin Zeitler Nov 18 '19 at 17:20

0 Answers0