java - Android:使用选择器更新自定义颜色属性

标签 java android xml android-selector

我想根据自定义状态定义在 Canvas 上绘画时应使用什么颜色。这就是我走了多远:

在 res/layout/content.xml 中:

<com.example.package.MyView
    app:primary_color="@drawable/my_selector"
/>

primary_color 是 res/values/attrs.xml 中定义的自定义属性:

<resource>
    <declare-styleable name="MyView">
        <attr name="primary_color" format="reference"/>
    </declare-styleable>
</resource>

my_selector 定义在 res/drawable/my_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.example.package">
    <item
        app:state_a="true"
        android:drawable="@drawable/red" />
    <item
        app:state_b="true"
        android:drawable="@drawable/orange" />
    <item
        app:state_c="true"
        android:drawable="@drawable/red" />
</selector>

红色、橙色和红色在 res/values/colordrawable.xml 中定义:

<resources>
    <drawable name="red">#f00</drawable>
    <drawable name="orange">#fb0</drawable>
    <drawable name="green">#0f0</drawable>
</resources>

在 MyView 中我可以获得这个可绘制对象:

StateListDrawable primaryColor;

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);

    try{

        primaryColor = (StateListDrawable) a.getDrawable(
            R.styleable.MyView_primary_color);
    }finally {
        a.recycle();
    }
}

primaryColor 在不同状态下正确更新,我可以通过调用来测试:

setBackground(primaryColor);

但我想在 Paint 中使用这种颜色,如下所示:

paint.setColor(primaryColor);

但这显然是不允许的。我尝试将 PrimaryColor 转换为 ColorDrawable它有 getColor() 方法,但我不知道如何做到这一点(如果可能的话)。

任何有关如何从选择器获取可在 View 中使用的颜色的建议都会很棒。

最佳答案

我找到了ColorStateList事实证明这正是我所需要的。以下是我当前实现的简化版本,以防其他人陷入与我相同的困境。

在 res/color/my_selector.xml 中

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"">

  <item app:state_weak="true" android:color="#F00" />
  <item app:state_average="true" android:color="#0F0" />
  <item app:state_strong="true" android:color="#00F" />
  <item android:color="#FA0" />
</selector>

在 res/layout/content.xml 中(这有另一个布局包裹着它,但这不相关)

<com.example.package.MyView
    android:id="@+id/strMeter"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:primary_color="@color/my_selector"
    />

primary_color 被定义为 res/values/attrs.xml 中的引用

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView">
        <attr name="primary_color" format="reference"/>
    </declare-styleable>
</resources>

我在 MyView 的构造函数中获取了对 ColorStateList 的引用:

ColorStateList primaryColor;

public PasswordStrengthBar(Context context, AttributeSet attrs) {
    super(context, attrs);

    try{
        primaryColor = a.getColorStateList(
            R.styleable.MyView_primary_color);
    }finally {
        a.recycle();
    }
}

当我想获取当前状态的颜色时:

int color = secondaryColor.getColorForState(
              getDrawableState(), primaryColor.getDefaultColor());

如果您像我一样实现自定义状态,那么您还必须重写 onCreateDrawableState 才能实际更新状态,但有大量文档/帖子涵盖了这一点。

关于java - Android:使用选择器更新自定义颜色属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41465741/

相关文章:

java - 无法使用 findFragmentById 访问我的 fragment

java - 如何从Java算法的乱序字符串中检索原始字符串

java - 为什么此代码有效?先赋值再声明?

java - 无法从 Scanner 类中的 nextLine() 分配字符串值

java - 我想更改我的应用程序默认语言

android - 进入应用前台调用特定代码

android - 关于 LayoutInflater 和 inflate

javascript - getElementsByTagName().length 在 Firefox/Internet Explorer 中不起作用

java - OpenCV Android Studio Java IP摄像机未连接

java - 将空标签解码到集合的新实例中