The question title is probably nonsensical. I am creating a bunch of custom views that will be placed in a single parent layout - a custom FrameLayout
.
These custom views have their own style attr which are set using the parent's style attr.
As an example, consider Parent
to be the custom FrameLayout
. Its style attr
is defined in attrs.xml
:
<attr name="parentStyleAttr" format="reference" />
The Child
also has its attr:
<attr name="childStyleAttr" format="reference" />
And Parent
defines its styleable attr as:
<declare-styleable name="Parent">
<attr name="childStyleAttr" />
</declare-styleable>
Child's
styleable attr:
<declare-styleable name="Child">
<attr name="childBgColor" format="color" />
</declare-styleable>
Following this, I define a style for the parent:
<style name="ParentStyle">
<item name="childStyleAttr">@style/ChildStyle</item>
</style>
and one for Child
:
<style name="ChildStyle">
<item name="childBgColor">@color/blah</item>
</style>
For Parent
, I set up parentStyleAttr
in the app's theme:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="parentStyleAttr">@style/ParentStyle</item>
</style>
Now, when Parent
is created, it inflates a layout containing Child
:
LayoutInflater.from(getContext()).inflate(R.layout.child, this, true);
During Child's
initialization, I need to read the value of the style attribute set in @style/ChildStyle
- childBgColor
.
This doesn't work:
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.Child, R.attr.childStyleAttr, R.style.ChildStyle);
The way I am currently reading attr/childBgColor
is:
public Child(Context context, AttributeSet attrs, int defStyleAttr) {
super(createThemeWrapper(context), attrs, defStyleAttr);
initialize(attrs, defStyleAttr, R.style.ChildStyle);
}
private static ContextThemeWrapper createThemeWrapper(Context context) {
final TypedArray forParent = context.obtainStyledAttributes(
new int[]{ R.attr.parentStyleAttr });
int parentStyle = forParent.getResourceId(0, R.style.ParentStyle);
forParent.recycle();
TypedArray forChild = context.obtainStyledAttributes(parentStyle,
new int[]{ R.attr.childStyleAttr });
int childStyleId = forChild.getResourceId(0, R.style.ChildStyle);
forChild.recycle();
return new ContextThemeWrapper(context, childStyleId);
}
void initialize(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
Context context = getContext();
final Resources res = getResources();
final TypedArray a = context.obtainStyledAttributes(R.styleable.Child);
....
}
I am not confident if this is the right approach. Can someone help shed some some light on this?
I would go for the simple solution which extending the Layout and create a custom layout that sends it attributes to it's children while adding them
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