How do I "cascade" the value of a custom attribute from a parent view to its child view?
This is easiest to explain using an example:
<com.example.CustomLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:percent="35" >
<com.example.CustomView
android:id="@+id/customView1"
app:percent="how-to-get-app:percent-value-here???"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.example.CustomLayout>
Here, CustomLayout
extends LinearLayout
. I have defined a custom attribute "percent" in attrs.xml
using <declare-styleable>
element. As you can see, I set percent to 35 in the XML for CustomLayout
.
I now want to pass in the same value to CustomView
(which extends View
) and which I will include in CustomLayout
. I am unable to find a way to do this in XML (it is easy to do this in code though).
I tried the following:
app:percent="@attr/percent"
app:percent="?attr/percent"
Both of these (expectedly) fail with NumberFormatException
at TypedArray#getInt()
.
So, any ideas on how to get this to work?
Although the idea comes a bit late and the method is not straight forward, I think it's still worth sharing. We can put custom attributes into a theme, so the attributes can be passed to all child views from the parent view where the theme is used (i.e., the attributes exist within the View Group).
Example as follows:
<integer name="percentage">35</integer>
<style name="CustomTheme" parent="suitable theme for your case">
<item name="percent">@integer/percentage</item>
</style>
<com.example.CustomLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:theme="@style/CustomTheme" >
<com.example.CustomView
android:id="@+id/customView1"
app:percent="?attr/percent" <!--Note: that's how it refers to the value,
however, re-assign the attribute value here is meaningless as attribute percent
should exist in all child views now. You can retrieve its value via
Theme.obtainStyledAttributes(R.style.CustomTheme, new int[] {R.attr.percent})
in every child view-->
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.example.CustomLayout>
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