I am unable to override attributes when using <include> in my Android layout files. When I searched for bugs, I found Declined Issue 2863:
"include tag is broken (overriding layout params never works)"
Since Romain indicates this works in the test suites and his examples, I must be doing something wrong.
My project is organized like this:
res/layout buttons.xml res/layout-land receipt.xml res/layout-port receipt.xml
The buttons.xml contains something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <Button .../> <Button .../> </LinearLayout>
And the portrait and landscape receipt.xml files look something like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> ... <!-- Overridden attributes never work. Nor do attributes like the red background, which is specified here. --> <include android:id="@+id/buttons_override" android:background="#ff0000" android:layout_width="fill_parent" layout="@layout/buttons"/> </LinearLayout>
What am I missing?
The <include> tag lets you to divide your layout into multiple files: it helps dealing with complex or overlong user interface.
Specifically, Android considers XML-based layouts to be resources, and as such, layout files are stored in the reslayout directory inside your Android project. Each XML file contains a tree of elements specifying a layout of widgets and containers that make up one View.
XML tags define the data and used to store and organize data. It's easily scalable and simple to develop. In Android, the XML is used to implement UI-related data, and it's a lightweight markup language that doesn't make layout heavy. XML only contains tags, while implementing they need to be just invoked.
I just found the issue. First, you can only override layout_* attributes, so the background won't work. That is documented behavior and simply an oversight on my part.
The real problem is found in LayoutInflater.java:
// We try to load the layout params set in the <include /> tag. If // they don't exist, we will rely on the layout params set in the // included XML file. // During a layoutparams generation, a runtime exception is thrown // if either layout_width or layout_height is missing. We catch // this exception and set localParams accordingly: true means we // successfully loaded layout params from the <include /> tag, // false means we need to rely on the included layout params. ViewGroup.LayoutParams params = null; try { params = group.generateLayoutParams(attrs); } catch (RuntimeException e) { params = group.generateLayoutParams(childAttrs); } finally { if (params != null) { view.setLayoutParams(params); } }
If the <include> tag does not include both layout_width and layout_height, the RuntimeException occurs and is silently handled, without any log statement even.
The solution is to always include both layout_width and layout_height when using the <include> tag, if you want to override any of the layout_* attributes.
My example should change to:
<include android:id="@+id/buttons_override" android:layout_width="fill_parent" android:layout_height="wrap_content" layout="@layout/buttons"/>
I submitted an enhancement request to allow all included attributes to be overridden:
Suppose I have two identical layouts other than the values of a
TextView
field. Presently, I either have modify the layout at runtime or duplicate the XML.For example to pass two parameters with values "hello" and "world" to layout1:
<include layout="@layout/layout1a" params="textView=hello|editText=world" />
layout1a.xml:
<merge><TextView text="@param/textView"><EditText hint="@param/editText"></merge>
An alternate implementation would break encapsulation and would allow the include statement to override values like:
<include layout="@layout/layout1b" overrides="@id/textView.text=hello|@id/editText.hint=world" />
layout1b.xml:
<merge><TextView id="@+id/textView"><EditText hint="@+id/editText"></merge>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With