Android 从父级获取子级的样式化属性';s样式定义
这个问题的标题可能是荒谬的。我正在创建一组自定义视图,这些视图将放置在一个单亲布局中—一个自定义Android 从父级获取子级的样式化属性';s样式定义,android,xml,attr,Android,Xml,Attr,这个问题的标题可能是荒谬的。我正在创建一组自定义视图,这些视图将放置在一个单亲布局中—一个自定义FrameLayout 这些自定义视图有自己的样式属性,这些样式属性是使用父视图的样式属性设置的 作为例子,考虑父/代码>为自定义 FrAMLayayOut。其样式attr在attrs.xml中定义: <attr name="parentStyleAttr" format="reference" /> 并且Parent将其可设置样式的属性定义为: <declare-styleabl
FrameLayout
这些自定义视图有自己的样式属性,这些样式属性是使用父视图的样式属性设置的
作为例子,考虑<代码>父/代码>为自定义<代码> FrAMLayayOut。其样式
attr
在attrs.xml
中定义:
<attr name="parentStyleAttr" format="reference" />
并且Parent
将其可设置样式的属性定义为:
<declare-styleable name="Parent">
<attr name="childStyleAttr" />
</declare-styleable>
接下来,我为父级定义了一个样式:
<style name="ParentStyle">
<item name="childStyleAttr">@style/ChildStyle</item>
</style>
对于Parent
,我在应用程序的主题中设置了parentStyleAttr
:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="parentStyleAttr">@style/ParentStyle</item>
</style>
在Child
初始化期间,我需要读取@style/ChildStyle
-childBgColor
中设置的style属性值
这不起作用:
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.Child, R.attr.childStyleAttr, R.style.ChildStyle);
我目前阅读的attr/childBgColor
是:
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);
....
}
我不确定这是否是正确的方法。有人能帮我解释一下吗?我会选择一个简单的解决方案,扩展布局并创建一个自定义布局,将其属性发送给它的孩子们。你的代码不起作用或者只是想改进它?@Nikmeyers我想知道我目前的方法是否正确。如果不是,什么是正确的方法?我可能会弄错,但是您描述的问题听起来像是最近的
appcompat
更新中实现的父主题继承:作者提到LayoutInflater.Factory2
是启用父主题继承的类。读取子主题中的xml属性并生成getter不是更简单吗?@BojanKseneman恐怕我不明白读取子对象中的xml属性会不会更简单…
这就是我要做的。为了让事情更清楚,我可以在AppTheme
下初始化childStyleAttr
,然后很好地阅读childBgColor
。但是如果我这样做,我必须初始化AppTheme
下所有子项的样式属性。相反,我想设置parentStyleAttr
,它应该处理所有子项的样式属性。您已经链接到addViewInLayout(查看子项、int索引、布局参数、boolean preventRequestLayout)
。如何使用此方法读取子项的样式属性
?通过重写此方法,您将有权访问已添加的每个子项,以便您能够以编程方式插入所需的属性,但我不寻找替代方法。根据android指南,样式信息应该使用属性设置。否则,就没有样式、属性等的用途,因为一切都可以在Java端完成。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="parentStyleAttr">@style/ParentStyle</item>
</style>
LayoutInflater.from(getContext()).inflate(R.layout.child, this, true);
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.Child, R.attr.childStyleAttr, R.style.ChildStyle);
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);
....
}