如何以编程方式创建ColorStateList?

Anu*_*ool 139 android android-color

我正在尝试ColorStateList使用这个以编程方式创建:

ColorStateList stateList = new ColorStateList(states, colors); 
Run Code Online (Sandbox Code Playgroud)

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

根据文件:

public ColorStateList (int[][] states, int[] colors) 
Run Code Online (Sandbox Code Playgroud)

在API级别1中添加

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

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

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

Can*_*ner 313

有关可用状态的列表,请参见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);
Run Code Online (Sandbox Code Playgroud)

  • 感谢关于"对立"状态的信息! (42认同)
  • 注意:请参阅Roger Alien的答案(及其第一条评论)以了解此处的状态顺序较差:因为"启用"是第一个,它将覆盖启用按钮时通常会出现的其他状态.最好把"启用"放在最后.(或者代替"启用",最后一个空/默认项目.) (4认同)
  • 不保留状态的按钮(不是切换/复选框)的状态的基本列表可能是"{按下}","{聚焦}","{ - 启用}","{}".对于切换,它可能是`{checked,pressed}},`{pressed}`,`{checked,focused}`,`{focused}`,`{checked}`,`{-enabled}`,`{} `.或忽略焦点的切换:`{checked,pressed}`,`{pressed}`,`{checked}`,`{-enabled}`,`{}`. (2认同)
  • 如果有人尝试其中任何解决方案,请注意 selecter.xml 中状态的顺序! (2认同)

Su-*_*ang 71

第一个维度是状态集数组,第二个维度是状态集本身.colors数组列出了每个匹配状态集的颜色,因此colors数组的长度必须与states数组的第一个维度相匹配(或者当状态为"used"时它会崩溃).这里和例子:

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
                        }
                    );
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

编辑示例: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>
Run Code Online (Sandbox Code Playgroud)

看起来像这样

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)
        }
);
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,要指定一个错误状态,您可以取反它的值,因此,如果要为未按下状态指定颜色,则应使用:new int [] {-android.R.attr.state_pressed} (2认同)
  • ......你可能犯的错误就是有一个像`{pressed}`,`{-pressed}`,`{focused}`,`{-focused`}这样的系列.问题是`{pressed}`和`{-pressed}`覆盖所有可能性(按下按钮或未按下按钮),因此不会使用后面列出的颜色. (2认同)

tse*_*tse 43

有时候这就足够了:

int colorInt = getResources().getColor(R.color.ColorVerificaLunes);
ColorStateList csl = ColorStateList.valueOf(colorInt);
Run Code Online (Sandbox Code Playgroud)


Rog*_*ien 19

不幸的是,这些解决方案都不适合我.

  1. 如果您最初没有设置按下状态,它将无法检测到它.
  2. 如果设置它,则需要定义空状态以添加默认颜色
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
        }
);
Run Code Online (Sandbox Code Playgroud)

这是源代码的构造函数:

/**
 * 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];
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 正如旁注:你必须像对待if-elseif那样对待它.它选择第一个为真的状态.因此,如果将state_enabled作为第一个状态,则将在state_pressed之前选择它 - 除非视图被禁用. (5认同)

are*_*lek 18

跳出Jonathan Ellis答案,在 Kotlin 中,您可以定义一个辅助函数,使代码更加地道且易于阅读,因此您可以改为编写以下代码:

val colorList = colorStateListOf(
    intArrayOf(-android.R.attr.state_enabled) to Color.BLACK,
    intArrayOf(android.R.attr.state_enabled) to Color.RED,
)
Run Code Online (Sandbox Code Playgroud)

colorStateListOf 可以这样实现:

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

我也有:

fun colorStateListOf(@ColorInt color: Int): ColorStateList {
    return ColorStateList.valueOf(color)
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以调用相同的函数名,无论是选择器还是单色。


Jon*_*lis 15

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

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
        )
)
Run Code Online (Sandbox Code Playgroud)