2016-09-13 4 views
2

Я внедрил пользовательский вид с настраиваемыми атрибутами, и я пытаюсь его стилизовать в теме. Я выполнил инструкции в this answer, но мой виджет не подбирает стиль из темы приложения.Добавить пользовательский стиль виджета в тему приложения

Обычай атрибуты для моего виджета:

<declare-styleable name="BarGraph"> 
    <attr name="barColour" format="color"/> 
    <attr name="barWidth" format="dimension"/> 
    <attr name="maxBarHeight" format="dimension"/> 
    <attr name="barWhiteSpace" format="dimension"/> 
</declare-styleable> 

Объявляем ссылку стиль:

<declare-styleable name="CustomTheme"> 
    <attr name="barGraphStyle" format="reference"/> 
</declare-styleable> 

Стиль мой виджет:

<style name="AppTheme.BarGraphStyle" parent="AppTheme"> 
    <item name="barColour">?attr/colorAccent</item> 
    <item name="barWidth">@dimen/bar_graph_bar_width</item> 
    <item name="maxBarHeight">@dimen/bar_graph_bar_max_height</item> 
    <item name="barWhiteSpace">@dimen/bar_white_space</item> 
</style> 

Добавить стиль к теме моего приложения:

<style name="AppTheme" parent="Theme.AppCompat.Light"> 
    ... 
    <item name="barGraphStyle">@style/AppTheme.BarGraphStyle</item> 
</style> 

Наконец, я получаю пользовательские атрибуты в конструктор моего пользовательского компонента:

TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.BarGraph); 
ColorStateList barColour = styledAttributes.getColorStateList(R.styleable.BarGraph_barColour); 
Log.d(TAG, "BarGraph: barColour = " + barColour); 

float barWidth = styledAttributes.getDimension(R.styleable.BarGraph_barWidth, -1); 
float maxHeight = styledAttributes.getDimension(R.styleable.BarGraph_maxBarHeight, -1); 
float barWhiteSpace = styledAttributes 
      .getDimension(R.styleable.BarGraph_barWhiteSpace, -1); 
    styledAttributes.recycle(); 
Log.d(TAG, "BarGraph: barWidth = " + barWidth); 
Log.d(TAG, "BarGraph: maxHeight = " + maxHeight); 
Log.d(TAG, "BarGraph: barWhiteSpace = " + barWhiteSpace); 

выхода журнала из конструктора:

D/BarGraph(6862): BarGraph: barColour = null 
D/BarGraph(6862): BarGraph: barWidth = -1.0 
D/BarGraph(6862): BarGraph: maxHeight = -1.0 
D/BarGraph(6862): BarGraph: barWhiteSpace = -1.0 

Если я применить стиль непосредственно на мой виджет, используя style="@style/AppTheme.BarGraphStyle", он правильно стирается, поэтому я знаю, что это не проблема с самим стилем.

Edit: мои конструкторы:

public BarGraph(Context context, @Nullable AttributeSet attrs) { 
    this(context, attrs, 0); 
} 

public BarGraph(Context context, @Nullable AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

    // grab all the custom styling values 
    TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.BarGraph); 
    ColorStateList barColour = styledAttributes.getColorStateList(R.styleable.BarGraph_barColour); 
    Log.d(TAG, "BarGraph: barColour = " + barColour); 

    float barWidth = styledAttributes.getDimension(R.styleable.BarGraph_barWidth, -1); 
    float maxHeight = styledAttributes.getDimension(R.styleable.BarGraph_maxBarHeight, -1); 
    float barWhiteSpace = styledAttributes .getDimension(R.styleable.BarGraph_barWhiteSpace, -1); 
    styledAttributes.recycle(); 

    Log.d(TAG, "BarGraph: barWidth = " + barWidth); 
    Log.d(TAG, "BarGraph: maxHeight = " + maxHeight); 
    Log.d(TAG, "BarGraph: barWhiteSpace = " + barWhiteSpace); 

    // other non-styling code... 
} 
+0

Can u plz опубликовать все конструкторы вашего пользовательского компонента? –

+0

@AndreClassen добавил их – AesSedai101

+1

'AppTheme.BarGraphStyle' не должен наследовать от целой темы. '' '' или '" android: Widget "' будут отличными родителями. В то время как у меня меняется имя, чтобы лучше отразить, что это * стиль *, а не * тема *. 'Widget.BarGraph' было бы неплохо. –

ответ

1

Конструкторы должны быть так:

public BarGraph(Context context, @Nullable AttributeSet attrs) { 
     this(context, attrs, R.attr.barGraphStyle); 
    } 

    public BarGraph(Context context, @Nullable AttributeSet attrs, @AttrRes int defStyle) { 
     super(context, attrs, defStyle); 

     // grab all the custom styling values 
     TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.BarGraph, defStyle, 0); 

     ... 
    } 
+0

Не будет ли это использовать по умолчанию? – AesSedai101

+0

@ AesSedai101 О чем вы беспокоитесь? 'R.attr.barGraphStyle' относится к стилю, определенному в' AppTheme'. Есть проблемы? – nshmura

+0

ах я пропустил это. Я дам ему попробовать, спасибо – AesSedai101

2

Изменить свой второй конструктор, как это,

public BarGraph(Context context, AttributeSet attrs) { 
     this(context, attrs, R.attr.barGraphStyle); 
    } 

И внутри вашего третьего конструктора , используйте эту строку

TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.BarGraph, defStyleAttr, R.style.AppTheme_BarGraphStyle); 

Вы пропустили эти строки. Он отлично работает для меня с этим кодом.

+0

'BarGraph (Context, AttributeSet)' - это contructor, вызываемый при раздувании XML. 'R.attr.barGraphStyle' является (необязательным) атрибутом темы, указывающим на стиль. 'R.style.AppTheme_BarGraphStyle' - это стиль, содержащий значения по умолчанию. Значения этого стиля по умолчанию всегда будут выбраны, если они не будут переопределены атрибутом темы barGraphsStyle или атрибутом style или direct. –

Смежные вопросы