tags:

views:

44

answers:

2

I'm in the middle of implementing themes for my application right now, and everything's been going really smooth until as of late. I've been using the android:background="?thin_border" tag to provide a background for linearlayouts with items that I want visually grouped together. The problem I'm running into is when I try to use this tag in an xml with a custom class as one of the elements, and try to add this background tag.

I've got an xml file that looks generally like so:

<?xml version="1.0" encoding="utf-8"?>
<com.atraudes.CustomLayout1 xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent"
    android:layout_gravity="fill_vertical">
    <LinearLayout android:orientation="vertical" 
        android:layout_height="fill_parent"
        android:layout_weight="0" 
        android:background="?thin_border" 
        android:layout_width="wrap_content" />
    ...
</com.atraudes.CustomLayout1>

and the custom class has two constructors:

public class CustomLayout1 extends LinearLayout {
    public CustomLayout1(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomLayout1(Context context) {
        super(context);
    }
    ...
}

with some other functions that store values, manipulate the data, etc. The custom layout class is only ever called directly in the xml, and the xml is inflated like so:

LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = (CustomLayout1) inflater.inflate(R.layout.customlayout1, null);

The problem I'm running into is that I'm getting these error messages:

10-27 17:13:15.312: ERROR/AndroidRuntime(4281): Uncaught handler: thread main exiting due to uncaught exception
10-27 17:13:15.351: ERROR/AndroidRuntime(4281): android.view.InflateException: Binary XML file line #7: Error inflating class java.lang.reflect.Constructor
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.LayoutInflater.createView(LayoutInflater.java:512)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:562)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:617)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at com.atraudes.CustomListAdapter.getView(CustomListAdapter.java:97)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.AbsListView.obtainView(AbsListView.java:1269)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.ListView.makeAndAddView(ListView.java:1623)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.ListView.fillDown(ListView.java:607)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.ListView.fillFromTop(ListView.java:664)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.ListView.layoutChildren(ListView.java:1481)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.AbsListView.onLayout(AbsListView.java:1113)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.Gallery.setUpChild(Gallery.java:813)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.Gallery.makeAndAddView(Gallery.java:757)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.Gallery.layout(Gallery.java:627)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.Gallery.onLayout(Gallery.java:339)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.layout(View.java:6133)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.ViewRoot.performTraversals(ViewRoot.java:929)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1482)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.os.Looper.loop(Looper.java:123)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.app.ActivityThread.main(ActivityThread.java:3948)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at java.lang.reflect.Method.invokeNative(Native Method)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at java.lang.reflect.Method.invoke(Method.java:521)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at dalvik.system.NativeStart.main(Native Method)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281): Caused by: java.lang.reflect.InvocationTargetException
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.widget.LinearLayout.<init>(LinearLayout.java:92)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at java.lang.reflect.Constructor.constructNative(Native Method)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.LayoutInflater.createView(LayoutInflater.java:499)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     ... 48 more
10-27 17:13:15.351: ERROR/AndroidRuntime(4281): Caused by: android.content.res.Resources$NotFoundException: File res/drawable/divider_horizontal_dark.9.png from drawable resource ID #0x0
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.content.res.Resources.loadDrawable(Resources.java:1641)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.content.res.TypedArray.getDrawable(TypedArray.java:548)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.<init>(View.java:1725)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.View.<init>(View.java:1674)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.view.ViewGroup.<init>(ViewGroup.java:271)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     ... 52 more
10-27 17:13:15.351: ERROR/AndroidRuntime(4281): Caused by: java.io.FileNotFoundException: res/drawable/divider_horizontal_dark.9.png
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.content.res.AssetManager.openNonAssetNative(Native Method)
10-27 17:13:15.351: ERROR/AndroidRuntime(4281):     at android.c

The error seems to be caused by the android:background="?thin_border" tag. If I remove it from the layout, it inflates fine, and the program continues on. As soon as I add it back in, I get these errors and the program stops.

I would be incredibly grateful of any input you might have. Thank you!

A: 

should look like this

<?xml version="1.0" encoding="utf-8"?>
<com.atraudes.CustomLayout1 xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="horizontal" 
   android:layout_height="wrap_content" 
   android:layout_width="fill_parent"
   android:layout_gravity="fill_vertical">
<LinearLayout android:orientation="vertical" 
    android:layout_height="fill_parent"
    android:layout_weight="0" 
    style="@styles/thin_border"
    android:layout_width="wrap_content" />

and your style should by

<style name="thin_boarder>
 <item name="android:background">@drawable/customstyle_button_editing</item>
</style>
schwiz
I don't understand. That's the same first line I already have in my xml file.
atraudes
see my edit your style is wrong too
schwiz
The ? I'm using references an attribute of the currently loaded theme. If I refer to a style directly, though, as you indicate, the xml loads, but the style does not get applied. I need to be able to reference an attribute of the current theme, instead of hard-coding it to a certain style.
atraudes
Correction: setting style="@styles/thin_border works fine, but trying to reference an attribute of the current theme does not.
atraudes
post your style, whats on line 7?
schwiz
The line 7 the error is referring to is in the xml layout. The theme element it's referencing in themes.xml is <item name="thin_border">@drawable/button_ready</item> Thanks for your help schwiz, I appreciate it!
atraudes
+1  A: 

After pulling my hair out over this for the past day (and much longer than that in the past), I figured out the problem. I was setting the theme on the activity before setContent(), which was applying the theme for the activity just fine. I finally figured out that running setTheme() on the context as well fixed the problem. The context holds the theme info, which gets passed to the custom view upon inflation. I assumed that setting the theme on the activity was setting it on the context as well :-/

int customTheme = R.style.customTheme;
setTheme(customTheme);
getApplicationContext().setTheme(customTheme);
setContentView(R.layout.mainactivitylayout);

The only other thing I did differently was during inflation:

v = (CustomLayout1) inflater.inflate(R.layout.customlayout1, parent, false);

parent being a parent layout. This was being done in a ListView adapter, so it was right there :-)

atraudes