Название вопроса, вероятно, бессмысленно. Я создаю кучу пользовательских представлений, которые будут помещены в один родительский макет - обычай FrameLayout
.Получить атрибуты стиля для ребенка из определения стиля родителя
Эти пользовательские виды имеют свой собственный стиль attr, которые заданы с использованием стиля attr родителя.
В качестве примера рассмотрим Parent
, чтобы быть обычным FrameLayout
. Его стиль attr
определяется в attrs.xml
:
<attr name="parentStyleAttr" format="reference" />
Child
также имеет Attr:
<attr name="childStyleAttr" format="reference" />
И Parent
определяет его styleable атр как:
<declare-styleable name="Parent">
<attr name="childStyleAttr" />
</declare-styleable>
Child's
styleable атр:
<declare-styleable name="Child">
<attr name="childBgColor" format="color" />
</declare-styleable>
После этого я определить стиль для родителя:
<style name="ParentStyle">
<item name="childStyleAttr">@style/ChildStyle</item>
</style>
и один для Child
:
<style name="ChildStyle">
<item name="childBgColor">@color/blah</item>
</style>
Для Parent
, я создал parentStyleAttr
в теме о приложении:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="parentStyleAttr">@style/ParentStyle</item>
</style>
Теперь, когда создается Parent
, оно раздувается S макет, содержащий Child
:
LayoutInflater.from(getContext()).inflate(R.layout.child, this, true);
Во время инициализации Child's
, мне нужно прочитать значение атрибута стиля, установленного в @style/ChildStyle
- childBgColor
.
Это не работает:
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);
....
}
Я не уверен, если это правильный подход. Может кто-то помочь пролить некоторый свет на это?
ваш код не работает или просто хотите улучшить? –
@NikMyers Я хочу знать, правильно ли мой текущий подход. И если это не так, какой правильный подход? – Vikram
Я могу ошибаться, но проблема, которую вы описываете, звучит как наследование родительской темы, которая была реализована в недавнем обновлении 'appcompat': https://chris.banes.me/2015/04/22/support-libraries -v22-1-0/# androidtheme Автор упоминает «LayoutInflater.Factory2» как класс, который позволяет наследование родительской темы. – hidro