2

I'm working on a project, and I'm converting the GUI over to Style sheets. I use a layout, and then a landscape/portrait set of style sheets. I use an inflator to inflate the layout, as I am dynamically adding and removing content, and the view itself is dynamically created and destroyed by an application which my code plugs into.

myView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.bearing_layout, parentView, false);

Error: Java.Lang.RuntimeException: Binary XML file, line 2: You must supply a layout_width attribute.

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/bearing_overall_layout">
    <LinearLayout 
        style = "@style/bearing_header_layout">
        <TextView android:id="@+id/header" 
            style = "@style/bearing_header"
            android:background="@drawable/transparentbackground"
            android:text="@string/bearing_title" />
    </LinearLayout>
    <RelativeLayout style="@style/BearingSelectListContainer"
        android:id="@+id/top_view">
        <LinearLayout 
            style="@style/BearingSelectList_linear_layout">
            <TextView style="@style/BearingSelectListTitle" 
                android:id="@+id/title"
                android:text="@string/bearing_title" />
            <ScrollView android:id="@+id/listScroller"
                style="@style/bearing_list_scroller">
                <LinearLayout
                    style="@style/bearing_scroll_list_linear_layout" >
                    <LinearLayout android:id="@+id/pointList"
                        style="@style/bearing_point_list">
                    </LinearLayout>
                </LinearLayout>
            </ScrollView>
        <LinearLayout 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" 
                android:layout_gravity="center_horizontal">
                <Button style="@style/BearingSelectListButton" android:id="@+id/view" android:text="@string/view_button" />
                <Button style="@style/BearingSelectListButton" android:id="@+id/my_loc" android:text="@string/my_loc_button" />
                <Button style="@style/BearingSelectListButton" android:id="@+id/center" android:text="@string/center_button" />
                <Button style="@style/BearingSelectListButton" android:id="@+id/exit" android:text="@string/exit_button" />
            </LinearLayout>
        </LinearLayout>
    </RelativeLayout>
</LinearLayout>

And the style sheet:

<resources>
<style name="bearing_overall_layout">
    <item name="android:orientation">vertical</item>
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">300dp</item>
</style>
<style name = "bearing_header_layout">
    <item name ="android:orientation">horizontal</item>
    <item name ="android:layout_width">fill_parent</item>
    <item name ="android:layout_height">wrap_content</item>
    <item name ="android:layout_alignParentTop">true</item>
    <item name ="android:gravity">center</item>
</style>
<style name="bearing_header">
    <item name = "android:padding">10dp</item>
    <item name = "android:textSize">18sp</item>
    <item name = "android:textStyle">bold</item>
    <item name = "android:layout_width">wrap_content</item>
    <item name = "android:layout_height">wrap_content</item>
    <item name = "android:layout_alignParentTop">true</item>
    <item name = "android:gravity">center</item>
</style>
<style name="GotoMgrsInput">
    <item name="android:textSize">18dp</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">300dp</item>
    <item name="android:background">#ff000000</item>
</style>
    <style name="BearingSelectMgrsInput">
    <item name="android:textSize">16sp</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_weight">1</item>
    <item name="android:typeface">monospace</item>
</style>
<style name="bearing_list_scroller">
    <item name="android:layout_width">fill_parent</item> 
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_weight">1</item>
    <item name="android:gravity">center</item>

</style>
<style name = "bearing_scroll_list_linear_layout">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">fill_parent</item>
    <item name="android:orientation">vertical</item>
    <item name="android:layout_marginBottom">10dp</item>
    <item name="android:gravity">center</item>  
</style>
<style name = "bearing_point_list">
    <item name="android:layout_width">fill_parent</item> 
    <item name="android:layout_height">fill_parent</item>
    <item name="android:layout_marginRight">1dip</item>
    <item name="android:orientation">vertical</item>
    <item name="android:gravity">center</item>
</style>

<style name="bearing_BearingSelectListContainer">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">fill_parent</item>
    <item name="android:background">#a000</item>
    <item name="android:layout_alignParentLeft">true</item>
    <item name="android:id">@+id/top_view</item>
    <item name="android:gravity">center</item>
    <item name="android:layout_alignParentLeft">false</item>
</style>
<style name="BearingSelectList_linear_layout">
    <item name="android:orientation">vertical</item>
    <item name="android:layout_height">fill_parent</item> 
    <item name="android:layout_width">fill_parent</item>

</style>
<style name="BearingSelectListTitle">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_gravity">center</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">24sp</item>
</style>    
<style name="bearing_BearingSelectListButton">
    <item name="android:layout_width">80dp</item>
    <item name="android:layout_height">wrap_content</item>
</style>
<style name="bearing_text_label">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_gravity">center</item> 
    <item name="android:shadowColor">#ff000000</item> 
    <item name="android:shadowDx">1</item>
    <item name="android:shadowDy">1</item> 
    <item name="android:shadowRadius">1</item> 
    <item name="android:textStyle">bold</item>
    <item name="android:clickable">false</item> 
    <item name="android:longClickable">false</item>
</style>
<style name="bearing_item_inner_layout">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:gravity">center</item>
</style>
<style name="bearing_specific_view_layout">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:orientation">horizontal</item>
    <item name="android:layout_alignParentLeft">true</item>
</style> 

Now if I hard define the android:width and android:height in the base layout everything else runs perfectly. This isn't really acceptable because I need different values for layout vs portrait, as well as for different builds of phones.

The next option is to set the rootView of inflate to null, which does get the layout params right (sort of...), BUT this causes null pointers when I try and access internal elements of the view which is returned.

It seems to me like inflate is just ignoring the style elements of the inflated view, and from this question:

Why does LayoutInflater ignore the layout_width and layout_height layout parameters I've specified?

I see why, but again this doesn't do me any good in this case as I've attempted the suggested approaches (see above) and I am still getting this error when using style sheets.

The only option I haven't tried is hard coding the values into the layout, and then programatically detecting the orientation of the screen and altering the layout params accordingly, but again this would need to be done for a variety of phone builds and seems to defeat the entire purpose of style sheets.

Anyone have any ideas?

Community
  • 1
  • 1
Nathaniel
  • 457
  • 5
  • 14

2 Answers2

7

I came across this question when searching for why my TextView was not properly inflating the xml parameters. Unlike the author's solution, I had to use the name of the parent LinearLayout that I was adding my TextView to.

TextView myTextView = (TextView) myInflater.inflate(R.layout.my_textview_xml, myLinearLayout, false);

This video was helpful in solving the problem:

http://www.youtube.com/watch?v=1Y0LlmTCOkM

Suragch
  • 935
  • 3
  • 9
  • 15
2

Ok,

So I've not gotten any responses, here is my work around:

Change this:

myView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.bearing_layout, parentView, false);

To this:

myView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.bearing_layout, null, false);

This will properly load your resources the FIRST TIME. Note: This WILL not detect layout changes for your lowest level view on orientation changes, though all subsequent view should work fine. To handle this we add a helper function:

genLayoutParams(yourView);

private void genLayoutParams(View reuse) { // apply whatever layout parameters you see fit, these are just examples.
    if (activity.getResources().getConfiguration().orientation == activity.getResources().getConfiguration().ORIENTATION_LANDSCAPE) {
        reuse.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.FILL_PARENT));

    }
    else {
        if (android.os.Build.VERSION.SDK_INT >= 13) {
            reuse.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    250));
        }

        else{
            reuse.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    300));
        }
    }
}

Hope that saves somone some frustration.

Nathaniel
  • 457
  • 5
  • 14