プログラムでColorStateListを作成するにはどうすればよいですか?


158

私はColorStateListこれを使用してプログラムで作成しようとしています:

ColorStateList stateList = new ColorStateList(states, colors); 

しかし、私は2つのパラメータが何であるかわかりません。

ドキュメントに従って:

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

APIレベル1で追加されました

状態から色への指定されたマッピングを返すColorStateListを作成します。

誰かが私にこれを作成する方法を教えてもらえますか?

状態の2次元配列の意味は何ですか?

回答:


343

利用可能な状態のリストについては、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);

45
「反対」の状態に関する情報をありがとう!
BVB 2014年

これを使用して、デザインライブラリからファブの色を変更できます。
Tapirboy 2015

5
注意:ここでの状態の順序が悪いことを理解するには、Roger Alienの回答(およびその最初のコメント)を参照してください。「有効」が最初なので、ボタンが有効なときに通常発生する他の状態を上書きします。「有効」を最後に置くことをお勧めします。(または、代わりに空/デフォルト項目が最後、「有効」の)
ToolmakerSteve

2
状態を保持しないボタンの状態の基本的なリスト(NOTトグル/チェックボックスが)あるかもしれません{pressed}{focused}{-enabled}{}。トグルのためにそれはあるかもしれません{checked, pressed}{pressed}{checked, focused}{focused}{checked}{-enabled}{}。またはフォーカスを無視トグル:{checked, pressed}{pressed}{checked}{-enabled}{}
ToolmakerSteve

誰かがこれらのソリューションのいずれかを試す場合は、selector.xmlのように状態の順序に注意してください!
アントン・マコフ

75

最初の次元は状態セットの配列で、2番目の次元は状態セット自体です。colors配列は、一致する各状態セットの色をリストします。したがって、colors配列の長さは、states配列の最初の次元と一致する必要があります(または、状態が「使用されている」とクラッシュします)。ここと例:

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

: "<あなたは、XML下記のアンドロイド=セレクタのxmlns"を表現する方法を伝えることができschemas.android.com/apk/res/androidを真の「アンドロイド:色= "色/白@" /: "state_pressed = <項目は、Android>" > <item android:color = "@ color / black" /> </ selector> "colorstatelistを使用します。
2014年

@SatishKumarは私の編集をチェックしますが、まだテストしていません。
Su-Au Hwang

3
偽の状態を指定するには、その値を無効にすることができるので、押されていないときの色を指定する場合は、次を使用する必要があります
。new

1
@tinsukEの発言に追加するには:ただし、リストの後半のアイテムを誤って抑制しないようにするには、ほとんどの状態で否定を入れても意味がありません。代わりに、デフォルト(空)のアイテムで「その他」の可能性をすべて処理します。new int[]{}最後-この回答の最後のコードブロックに示されています。私が通常使用する唯一の否定された値は「有効」です。別の例は、あなたが3つの異なる色をしたい場合:「集中+を押す」、「+押されていない集束」、あなたは、単に置くことができ、「+押す焦点を当てていません」{focused, pressed}{focused}{pressed}。最初の「真」のものが使用されます。
ToolmakerSteve

2
...あなたが作るかもしれない間違いのようなシリーズを持つことで{pressed}{-pressed}{focused}{-focused}。問題は、すべての可能性(ボタンが押されているか押されていないか){pressed}{-pressed}カバーしているため、後でリストされている色が使用されないことです。
ToolmakerSteve

64

時にはこれで十分でしょう:

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

20

残念ながら、どの解決策も私にはうまくいきません。

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

これはソースコードのコンストラクタです:

/**
 * 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];
            }
        }
    }
}

5
補足として:if-elseifと同じように扱う必要があります。真である最初の状態を選択します。したがって、state_enabledが最初の状態である場合、ビューが無効でない限り、state_pressedの前に選択されます。
LeoFarage 2016年

FWIW、あなたはデフォルトの要素を最後に持っているので、私は最初の "有効な"要素があなたに何の役にも立たないと思います。完全に削除しませんか?
ToolmakerSteve

18

ColorListKotlinでプログラムによって作成する方法の例を次に示します。

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

また、Kotlinヘルパー関数については、以下の私の回答を参照しください。
arekolek

7

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())
}

私も持っています:

fun colorStateListOf(@ColorInt color: Int): ColorStateList {
    return ColorStateList.valueOf(color)
}

そのため、セレクターでも単色でも同じ関数名を呼び出すことができます。


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

2

リソースを使用する場合、Colors.xml

int[] colors = new int[] {
                getResources().getColor(R.color.ColorVerificaLunes),
                getResources().getColor(R.color.ColorVerificaMartes),
                getResources().getColor(R.color.ColorVerificaMiercoles),
                getResources().getColor(R.color.ColorVerificaJueves),
                getResources().getColor(R.color.ColorVerificaViernes)

        };

ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{colors[0]}); 

    example.setBackgroundTintList(csl);

2
getResources()それが今で推奨されていませんContextCompat.getColor(this,R.color.colorname);ContextCompat.getColor(getActivity(),R.color.colorname);フラグメントでの使用のために
iBobb

他のリーダーを明確にするためにnew int[0](最初のパラメーターのリストの要素として)は長さゼロの配列であり、デフォルトの色の設定を表します。これは唯一の要素です。つまり、色合いはボタンのすべての状態に適用されます。これはnew int[]{}、ロジャーエイリアンの回答に見られるものと同等です。
ToolmakerSteve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.