【问题标题】:Add custom widget styling to app theme将自定义小部件样式添加到应用主题
【发布时间】:2016-09-13 13:46:29
【问题描述】:

我已经实现了一个带有自定义属性的自定义视图,我正在尝试在主题中设置它的样式。我已按照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",它的样式正确,所以我知道样式本身没有问题。

编辑:我的构造函数:

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...
}

【问题讨论】:

  • 你能发布你自定义组件的所有构造函数吗?
  • @AndreClassen 添加了他们
  • AppTheme.BarGraphStyle 不应该从整个主题继承。 """android:Widget" 将是伟大的父母。同时更改名称以更好地反映它是 style 而不是 themeWidget.BarGraph 会很好。

标签: android android-theme


【解决方案1】:

像这样改变你的第二个构造函数,

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);

你错过了这些行。这段代码对我来说非常适合。

【讨论】:

  • BarGraph(Context, AttributeSet) 是从 XML 膨胀时调用的构造函数。 R.attr.barGraphStyle 是指向样式的(可选)主题属性。 R.style.AppTheme_BarGraphStyle 是一种包含默认值的样式。除非它们被barGraphsStyle 主题属性或style 属性或直接属性覆盖,否则将始终选择来自此默认样式的值。
【解决方案2】:

构造函数应该是这样的:

    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);

        ...
    }

【讨论】:

  • 那不只是使用默认值吗?
  • @AesSedai101 你在担心什么? R.attr.barGraphStyle 指的是AppTheme 中定义的样式。有问题吗?
猜你喜欢
  • 2011-05-28
  • 2015-08-05
  • 2018-02-24
  • 1970-01-01
  • 2014-04-08
  • 2015-11-19
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多