如何以编程方式创建ColorStateList?

时间:2013-03-21 09:04:55

标签: android android-color

我正在尝试使用以下方式以编程方式创建ColorStateList

ColorStateList stateList = new ColorStateList(states, colors); 

但我不确定这两个参数是什么。

根据文件:

public ColorStateList (int[][] states, int[] colors) 
     

在API级别1中添加

     

创建一个ColorStateList,它返回从状态到颜色的指定映射。

有人可以解释一下如何创建这个吗?

状态二维数组的含义是什么?

8 个答案:

答案 0 :(得分:282)

请参阅http://developer.android.com/reference/android/R.attr.html#state_above_anchor以获取可用状态列表。

如果你想为禁用,未聚焦,未选中状态等设置颜色,只需否定状态:

int[][] states = new int[][] {
    new int[] { android.R.attr.state_enabled}, // enabled
    new int[] {-android.R.attr.state_enabled}, // disabled
    new int[] {-android.R.attr.state_checked}, // unchecked
    new int[] { android.R.attr.state_pressed}  // pressed
};

int[] colors = new int[] {
    Color.BLACK,
    Color.RED,
    Color.GREEN,
    Color.BLUE
};

ColorStateList myList = new ColorStateList(states, colors);

答案 1 :(得分:67)

第一个维度是状态集数组, 第二个是国家自己设定的。 colors数组列出了每个匹配状态集的颜色,因此colors数组的长度必须与states数组的第一个维度相匹配(或者当状态为&#34时使用它会崩溃")。 这里和例子:

ColorStateList myColorStateList = new ColorStateList(
                        new int[][]{
                                new int[]{android.R.attr.state_pressed}, //1
                                new int[]{android.R.attr.state_focused}, //2
                                new int[]{android.R.attr.state_focused, android.R.attr.state_pressed} //3
                        },
                        new int[] {
                            Color.RED, //1
                            Color.GREEN, //2
                            Color.BLUE //3
                        }
                    );

希望这会有所帮助。

编辑示例: 一个xml颜色状态列表,如:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/white"/>
    <item android:color="@color/black"/>
</selector>

看起来像这样

ColorStateList myColorStateList = new ColorStateList(
        new int[][]{
                new int[]{android.R.attr.state_pressed},
                new int[]{}
        },
        new int[] {
                context.getResources().getColor(R.color.white),
                context.getResources().getColor(R.color.black)
        }
);

答案 2 :(得分:26)

有时这就足够了:

int colorInt = getResources().getColor(R.color.ColorVerificaLunes);
ColorStateList csl = ColorStateList.valueOf(colorInt);

答案 3 :(得分:15)

不幸的是,这些解决方案都不适用于我。

  1. 如果您最初没有设置按下状态,则无法检测到它。
  2. 如果您设置了它,那么您需要定义空状态以添加默认颜色
  3. ColorStateList themeColorStateList = new ColorStateList(
            new int[][]{
                    new int[]{android.R.attr.state_pressed},
                    new int[]{android.R.attr.state_enabled},
                    new int[]{android.R.attr.state_focused, android.R.attr.state_pressed},
                    new int[]{-android.R.attr.state_enabled},
                    new int[]{} // this should be empty to make default color as we want
            },
            new int[]{
                    pressedFontColor,
                    defaultFontColor,
                    pressedFontColor,
                    disabledFontColor,
                    defaultFontColor
            }
    );
    

    这是源代码构造函数:

    /**
     * Creates a ColorStateList that returns the specified mapping from
     * states to colors.
     */
    public ColorStateList(int[][] states, int[] colors) {
        mStateSpecs = states;
        mColors = colors;
    
        if (states.length > 0) {
            mDefaultColor = colors[0];
    
            for (int i = 0; i < states.length; i++) {
                if (states[i].length == 0) {
                    mDefaultColor = colors[i];
                }
            }
        }
    }
    

答案 4 :(得分:3)

我的用于创建ColorStateList

的构建器类
private class ColorStateListBuilder {
    List<Integer> colors = new ArrayList<>();
    List<int[]> states = new ArrayList<>();

    public ColorStateListBuilder addState(int[] state, int color) {
        states.add(state);
        colors.add(color);
        return this;
    }

    public ColorStateList build() {
        return new ColorStateList(convertToTwoDimensionalIntArray(states),
                convertToIntArray(colors));
    }

    private int[][] convertToTwoDimensionalIntArray(List<int[]> integers) {
        int[][] result = new int[integers.size()][1];
        Iterator<int[]> iterator = integers.iterator();
        for (int i = 0; iterator.hasNext(); i++) {
            result[i] = iterator.next();
        }
        return result;
    }

    private int[] convertToIntArray(List<Integer> integers) {
        int[] result = new int[integers.size()];
        Iterator<Integer> iterator = integers.iterator();
        for (int i = 0; iterator.hasNext(); i++) {
            result[i] = iterator.next();
        }
        return result;
    }
}

示例使用

ColorStateListBuilder builder = new ColorStateListBuilder();
builder.addState(new int[] { android.R.attr.state_pressed }, ContextCompat.getColor(this, colorRes))
       .addState(new int[] { android.R.attr.state_selected }, Color.GREEN)
       .addState(..., some color);

if(// some condition){
      builder.addState(..., some color);
}
builder.addState(new int[] {}, colorNormal); // must add default state at last of all state

ColorStateList stateList = builder.build(); // ColorStateList created here

// textView.setTextColor(stateList);

答案 5 :(得分:2)

如果您使用资源Colors.xml

NOT NULL

答案 6 :(得分:2)

这是一个如何在Kotlin中以编程方式创建ColorList的示例:

val colorList = ColorStateList(
        arrayOf(
                intArrayOf(-android.R.attr.state_enabled),  // Disabled
                intArrayOf(android.R.attr.state_enabled)    // Enabled
        ),
        intArrayOf(
                Color.BLACK,     // The color for the Disabled state
                Color.RED        // The color for the Enabled state
        )
)

答案 7 :(得分:2)

answer by Jonathan Ellis开始,您可以在Kotlin中定义一个辅助函数,以使代码更加惯用且易于阅读,因此您可以编写以下代码:

val colorList = colorStateListOf(
    intArrayOf(-android.R.attr.state_enabled) to Color.BLACK,
    intArrayOf(android.R.attr.state_enabled) to Color.RED
)

colorStateListOf可以这样实现:

fun colorStateListOf(vararg mapping: Pair<IntArray, Int>): ColorStateList {
    val (states, colors) = mapping.unzip()
    return ColorStateList(states.toTypedArray(), colors.toIntArray())
}