【问题标题】:Custom attr get color returns invalid values自定义 attr 获取颜色返回无效值
【发布时间】:2013-07-17 13:17:53
【问题描述】:

我有一个自定义视图,我想在其中设置文本视图的颜色。

我有

attrs.xml

<declare-styleable name="PropertyView">
    <attr name="propertyTitle" format="string" localization="suggested" />
    <attr name="showTitle" format="boolean" />
    <attr name="propertyTextColor" format="color" />
    <attr name="propertyTextSize" format="dimension" />
</declare-styleable>

我在布局文件中设置了

<com.something.views.PropertyView
    android:id="@+id/dwf_rAwayTeamTimePenaltyInput"
    style="@style/mw"
    propertyview:propertyTextSize="16sp"
    propertyview:propertyTitle="@string/AwayTeam"
    propertyview:showTitle="true"
    propertyview:propertyTextColor="@color/textLight" />

我在我的代码中设置了它

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PropertyView, 0, 0);

    showTitle = a.getBoolean(R.styleable.PropertyView_showTitle, false);
    String title = a.getString(R.styleable.PropertyView_propertyTitle);
    float textSize = a.getDimension(R.styleable.PropertyView_propertyTextSize, -1);
    int color = a.getColor(R.styleable.PropertyView_propertyTextColor, -1);
    textSize = textSize / getResources().getDisplayMetrics().scaledDensity;
    if(BuildConfig.DEBUG) Log.e(getClass().getName(), "Color set to: " + color);

    setShowTitle(showTitle);
    setTitle(title);
    if(textSize >= 0) mTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
    if(color != -1) mTitleTextView.setTextColor(color);

    a.recycle();

但是颜色一直返回-1。 我还尝试将颜色设置为 #000 当我这样做时,我得到的值为 -16777216

我也试过 a.getInteger 和 a.getInt

有人遇到过这个问题或建议吗?

解决方案,感谢 Alex Fu

getColor 无法处理引用

它现在正在使用

ColorStateList color = a.getColorStateList(R.styleable.PropertyView_propertyTextColor);
mTitleTextView.setTextColor(color);

【问题讨论】:

    标签: android android-custom-view


    【解决方案1】:

    您在示例中使用了对颜色的引用,但是根据您的 attrs.xml 文件,该属性必须是颜色类型,而不是引用。这可能是为什么当您使用十六进制颜色代码时它可以工作,但使用返回 -1 的引用。

    如果您确实将格式更改为引用,您还应该将检索它的方法从 a.getColor() 更改为 a.getColorStateList()

    【讨论】:

    • 您是否更改了 attrs.xml 中引用的格式?如果是这样,您是否也更改了a.getColor() 方法?您应该尝试改用a.getColorStateList()getColorStateList 既能看懂纯色,也能看懂引用。
    • 谢谢 =) getColor 无法处理引用是愚蠢的,但它可能有充分的理由。
    • Ps 格式应该保持颜色,而不是参考,或者可能两者兼而有之,但对我来说颜色仍然有效,允许我使用#xxx 和 @color/xxx
    • 如果没有设置属性会返回null
    【解决方案2】:

    这是attrs 的某种错误。

    以下工作完美。


    attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <!-- Your View -->
        <declare-styleable name="YourView">
            <attr name="tint_color" format="reference" /> <!-- Important -->
            <attr name="ripple_drawable" format="reference" /> <!-- Important -->
        </declare-styleable>
    
    </resources>
    

    YourView.java

    public YourView(Context context) {
        this(context, null);
    }
    
    public YourView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public YourView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    
        // Get attrs
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.YourView, defStyleAttr, 0);
    
        // Set tint
        int tintStyle = R.styleable.YourView_tint_color;
        if (a.hasValue(tintStyle)) {
            mTintColor = a.getResourceId(tintStyle, 0); // Important
            setTint(mTintColor);
        }
    
        // Set Ripple
        int rippleStyle = R.styleable.YourView_ripple_drawable;
        if (a.hasValue(rippleStyle)) {
            mRippleDrawable = a.getResourceId(rippleStyle, 0); // Important
            setRipple(mRippleDrawable);
        }
    
        // End
        a.recycle();
    }
    

    用法

    <com.your.app.YourView
        ...
        app:ripple_drawable="@drawable/ripple_default"
        app:tint_color="@color/colorWhite" />
    

    【讨论】:

      【解决方案3】:

      如果你想让每一种颜色都起作用

      • 十六进制:#ff0000
      • 色彩资源:@color/primary
      • 颜色选择器:@color/primaryWithStates

      您需要将您的属性定义为颜色和参考

      <attr name="propertyTextColor" format="color|reference" />
      

      然后您只需使用 getColorStateList 访问该值

      val colors = attr.getColorStateList(R.styleable.PropertyView_propertyTextColor)
      titleTextView.setTextColor(colors)
      

      对于您想自己消化ColorStateList的高级需求

      • 在前两种情况下,您可以使用 colors.defaultColor
      • 如果你使用了选择器,你必须调用方法getColorForState

      所以,提取颜色的最简单方法是这样做

      val currentColor = colors.getColorForState(drawableState, colors.defaultColor)
      // do whatever you want with the color
      

      如果当前状态有颜色则返回颜色,否则返回默认颜色

      注意:getColorForState应该放在drawableStateChanged()方法中,每次状态变化时都会得到通知

      【讨论】:

        猜你喜欢
        • 2018-02-14
        • 2012-03-05
        • 1970-01-01
        • 2021-09-02
        • 2011-09-12
        • 2021-06-01
        • 2014-01-19
        • 1970-01-01
        • 2014-06-12
        相关资源
        最近更新 更多