4

I've got a drawable background (called card_background_selector_light) that basically looks like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/card_state_pressed_light" android:state_pressed="true" />
    <item android:drawable="@drawable/card_background_light" />
</selector>

I've got an almost identical drawable called card_background_selector_dark. Based on the theme I'd now like to show one or the other.

To do this, I've defined an attribute in attrs.xml:

<attr name="listItemBackground" format="reference"></attr>

And included it in my two styles:

<style name="AppThemeDark" parent="android:Theme.Holo">
    <item name="listItemBackground">@drawable/card_background_selector_dark</item>
</style>

and

<style name="AppThemeLight" parent="android:Theme.Holo.Light">
    <item name="listItemBackground">@drawable/card_background_selector_light</item>
</style>

The actual LinearLayout now looks like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="?attr/listItemBackground">

</LinearLayout>

It all works just fine in the Android Studio preview (I can change the theme and it changes accordingly), but once I try to run it on an actual device I get the following exception:

android.view.InflateException: Binary XML file line #11: Error inflating class <unknown>
    at android.view.LayoutInflater.createView(LayoutInflater.java:620)
    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
    at org.jhi.android.germinatescan.adapter.ListRowAdapter.getView(ListRowAdapter.java:54)
    at android.widget.AbsListView.obtainView(AbsListView.java:2255)
    at android.widget.ListView.makeAndAddView(ListView.java:1790)
    at android.widget.ListView.fillDown(ListView.java:691)
    at android.widget.ListView.fillFromTop(ListView.java:752)
    at android.widget.ListView.layoutChildren(ListView.java:1630)
    at android.widget.AbsListView.onLayout(AbsListView.java:2087)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:690)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
    at android.view.View.layout(View.java:14817)
    at android.view.ViewGroup.layout(ViewGroup.java:4631)
    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1983)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1740)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
    at android.view.Choreographer.doCallbacks(Choreographer.java:574)
    at android.view.Choreographer.doFrame(Choreographer.java:544)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.reflect.InvocationTargetException
     at java.lang.reflect.Constructor.constructNative(Native Method)
     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
     at android.view.LayoutInflater.createView(LayoutInflater.java:594)
     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
     at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
     at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
     at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
     at org.jhi.android.germinatescan.adapter.ListRowAdapter.getView(ListRowAdapter.java:54)
     at android.widget.AbsListView.obtainView(AbsListView.java:2255)
     at android.widget.ListView.makeAndAddView(ListView.java:1790)
     at android.widget.ListView.fillDown(ListView.java:691)
     at android.widget.ListView.fillFromTop(ListView.java:752)
     at android.widget.ListView.layoutChildren(ListView.java:1630)
     at android.widget.AbsListView.onLayout(AbsListView.java:2087)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
     at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:690)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
     at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
     at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
     at android.view.View.layout(View.java:14817)
     at android.view.ViewGroup.layout(ViewGroup.java:4631)
     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1983)
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1740)
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
     at android.view.Choreographer.doCallbacks(Choreographer.java:574)
     at android.view.Choreographer.doFrame(Choreographer.java:544)
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
     at android.os.Handler.handleCallback(Handler.java:733)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:136)
     at android.app.ActivityThread.main(ActivityThread.java:5001)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
     at dalvik.system.NativeStart.main(Native Method)
 Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f010002 a=-1}

I've read a lot of other threads (like this one and this one) here that basically do it the same way, but somehow it doesn't work for me. Any ideas?

Update

As requested, here is the onCreate() method of my activity:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    setTheme(preferences.getBoolean(PreferenceUtils.PREF_THEME, isDefaultThemeDark()) ? DARK_THEME : LIGHT_THEME);

    setContentView(R.layout.activity_main);

    INSTANCE = this;

    /* Make sure the default preferences are set */
    PreferenceUtils.setDefaults(this);

    databaseHandler = new DatabaseHandler(this);

    List<Row> items = databaseHandler.getAllItems();
    adapter = new ListRowAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, items);

    if (items.size() > 0)
    {
        Row row = items.get(items.size() - 1);
        int col = row.getLastFilledColumn() + 1;

        if (col == getNrOfBarcodes())
        {
            currentColumn = 0;
        }
        else
        {
            currentColumn = col;
            currentListRow = row;
        }
    }

    listView = (ListView) findViewById(R.id.list_scanned_items);
    listView.setAdapter(adapter);

    hiddenInput = (EditText) findViewById(R.id.input);
    hiddenInput.setOnKeyListener(this);
    hiddenInput.requestFocus();

    /* Redirect every focus from the list view to the input text */
    listView.setOnFocusChangeListener(this);

    setCodeFormats();
}
Community
  • 1
  • 1
Baz
  • 36,440
  • 11
  • 68
  • 94

2 Answers2

4

You are using application context to inflate the list items. Try using the context of the activity.

adapter = new ListRowAdapter(this, android.R.layout.simple_list_item_1, items);
Abhishek V
  • 12,488
  • 6
  • 51
  • 63
  • Huh, well that was unexpected. But I guess it makes sense. Thanks a lot! I was trying to fix this for hours. Your bounty reward will have to wait for 22 hours. – Baz Oct 10 '14 at 15:45
  • That also explains why it was working properly in other parts of the application, but not here. – Baz Oct 10 '14 at 15:48
  • 2
    Yeah..It's little confusing when to use what type of context..when you use application context, inflation will be done with the default theme for the system on which you are running, not what’s defined in your application. [this article](http://www.doubleencore.com/2013/06/context/) has pretty good explanation about the context. Especially **Context Capabilities** topic. – Abhishek V Oct 10 '14 at 15:57
0

This error occurs if we don't set theme from the activity class. Make sure to call activity.setTheme(); method before setContentView call.

Manish
  • 983
  • 1
  • 9
  • 27
  • 1
    I do call `setTheme()` – Baz Oct 08 '14 at 15:03
  • Just for testing purpose, have you tried to replace @drawable/card_background_selector_dark with some color or actual image instead of drawable xml. Please also paste your activity code. – Manish Oct 08 '14 at 15:14
  • Colors are just the same, tried that as well. Posting the whole activity code may be overkill. If you can let me know which part exactly you're interested in, I can post that instead. – Baz Oct 08 '14 at 15:18
  • you can post, OnCreate method of the Activity – Manish Oct 08 '14 at 15:26
  • You are setting boolean inside setTheme() but it should be R.style.AppThemeDark. It should be one of the style id. – Manish Oct 08 '14 at 17:39
  • Please take a closer look, I *am* setting the theme id, not a boolean. It's a ternary operator that chooses between the two themes – Baz Oct 08 '14 at 17:41