web-dev-qa-db-ja.com

フォーカス/プレスでImageButtonの色合いを変更するにはどうすればよいですか

アプリにImageButtonがあり、ボタンがpressed/focusedのときに画像の色合いを変更する必要があります。次のようなXMLファイルからImageButtonを取得するようにsrcを設定しています:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <!-- pressed -->
    <item 
        Android:state_pressed="true"
        Android:tint="@color/black"
        Android:drawable="@drawable/search"
        />

    <!-- focused -->
    <item 
        Android:state_focused="true"
        Android:tint="@color/black"
        Android:drawable="@drawable/search"
        />

    <!-- default -->
    <item
        Android:tint="@null"
        Android:drawable="@drawable/search"
        />

</selector>

ただし、ImageButtonが押されたりフォーカスが合ったりした場合、色合いは適用されません。画像は通常どおり表示されます。黒はいつものように#000000として定義されています。何か案は?

56
Joseph Earl

次の方法で、コードで色合いを簡単に変更できます。

ImageButton button = (ImageButton) this.findViewById(R.id.button_i_want_to_modify);
button.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

それが役に立てば幸い。

JS

89
Jeff

Xmlだけを使用して行う方法を次に示します。描画可能なフォルダーにセレクターを作成します。例:touch_selector.xml

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

    <!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
    <item Android:state_pressed="true" Android:color="@color/semi_slate" />

    <!-- When the view is "activated".  In SINGLE_CHOICE_MODE, it flags the active row
     of a ListView -->
    <item Android:state_activated="true" Android:color="@color/semi_slate" />

    <!-- Default, "just hangin' out" state. -->
    <item Android:color="@Android:color/transparent" />
</selector>

Xmlの画像ビューで、Android:tint属性を上記で作成したドロウアブルに設定します。

Android:tint = "@drawable/touch_selector"

コード全体は次のようになりました。

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/poster"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:adjustViewBounds="true"
Android:scaleType="centerCrop"
Android:tint="@drawable/touch_selector" />

これは、プレスまたはアクティブ時にImageViewに色合いを付けるためのすべてxmlソリューションです。 ImageButtonについても同様のことができます

これは21以上のAPIレベルでのみ機能することに注意してください。

17

これをXMLで(少なくともAPI 21以降で)行う方法を見つけました。

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_pressed="true" >
        <bitmap
            Android:src="@drawable/search"
            Android:tint="@color/black"
            />
    </item>
    <item Android:drawable="@drawable/search"/>
</selector>

ビットマップに濃淡を設定することにより、タッチをインターセプトしたり、ImageViewまたはImageButtonをサブクラス化することなく、同じDrawableをxmlで再利用できます。

セレクタが作成されたら、それをImageViewまたはImageButtonのsrcとして適用します。

7
ckern

最後に、API <21のソリューションを見つけました。

Button more = (Button) findViewById(R.id.more);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
    more.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
} else {
    Drawable wrapDrawable = DrawableCompat.wrap(more.getBackground());
    DrawableCompat.setTint(wrapDrawable, color));
    more.setBackgroundDrawable(DrawableCompat.unwrap(wrapDrawable));
}

これにより、誰かが2時間失わないようになりますように!

6
bt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        bt.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        bt.clearColorFilter(); // White Tint
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });
2
Fu-Lung Chen

ここで、XMLでこれを行う方法を知りたい人のために、いくつかの要求があることに気付きました。実際には非常に簡単です。これは、layer-list

ボタンのドロウアブル(drawable/some_button.xml):

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_pressed="true" Android:drawable="@drawable/some_button_highlighted" />
    <item Android:drawable="@drawable/some_button_image" />
</selector>

そして、これはハイライトされたドロウアブル(drawable/some_button_highlighted.xml)です

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@drawable/some_button_image"/>
    <item>
        <shape>
            <solid Android:color="@color/highlighted_button_color" />
        </shape>
    </item>
</layer-list>

これで、他のxmlでこれを使用できます。

...
Android:drawable="@drawable/some_button"
...

これが将来誰かに役立つことを願っています。

1
aeskreis

Xmlから色(色合い)を設定できます。

transparentAndroid:background="@null"backgroundの場合、tintを使用します。

<ImageButton
     Android:layout_width="wrap_content"
     Android:layout_height="fill_parent"
     Android:tint="@color/Amber_200"
     Android:background="@null"
     Android:src="@drawable/back_selector" />
1
user4813855

私がやっていることは、関数setColorFilterを持つカスタムボタンを追加することです。

このように、xmlで新しいボタンを使用できます。

public class CustomButton extends Button {

public CustomButton(Context context) {
    super(context);
}

public CustomButton(Context context, AttributeSet attributes) {
    super(context, attributes);
};

@Override
public boolean onTouchEvent(MotionEvent event) {
    int maskedAction = event.getActionMasked();
    if (maskedAction == MotionEvent.ACTION_DOWN)
        getBackground().setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
    else if (maskedAction == MotionEvent.ACTION_UP)
        getBackground().setColorFilter(null);
    return super.onTouchEvent(event);
}}

およびImageButton用

public class CustomImageButton extends ImageButton {

public CustomImageButton(Context context) {
    super(context);
}

public CustomImageButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int maskedAction = event.getActionMasked();
    if (maskedAction == MotionEvent.ACTION_DOWN)
        setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
    else if (maskedAction == MotionEvent.ACTION_UP)
        setColorFilter(null);
    return super.onTouchEvent(event);
}}
1