Android 如何在焦点/按下时更改 ImageButton 的色调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3024983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:21:14  来源:igfitidea点击:

How do I change the tint of an ImageButton on focus/press

androidimageselectorimagebuttontint

提问by Joseph Earl

I have an ImageButtonin my app and I need to change the tint of the image when the button is pressed/focused. I have the ImageButtonset to get its srcfrom an XML file which as follows:

我的ImageButton应用程序中有一个,当按钮为 时,我需要更改图像的色调pressed/focused。我ImageButton有一套src从 XML 文件中获取它的设置,如下所示:

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

However the tint isn't applied when the ImageButtonis pressed or focused - the image just displays as normal. The color black is defined as #000000as always. Any ideas?

但是,在ImageButton按下或聚焦时不会应用色调- 图像只是正常显示。黑色#000000一如既往地被定义。有任何想法吗?

回答by Jeff

You can change the tint, quite easily in code via:

您可以通过以下方式在代码中轻松更改色调:

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

Hope it helps.

希望能帮助到你。

JS

JS

回答by Rashi Karanpuria

Here is how to do it using just xml. In your drawable folder create a selector. Eg: touch_selector.xml

以下是仅使用 xml 的方法。在您的 drawable 文件夹中创建一个选择器。例如: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>

In my Image view in xml I set the android:tint attribute to the drawable created above.

在我的 xml 图像视图中,我将 android:tint 属性设置为上面创建的可绘制对象。

android:tint = "@drawable/touch_selector"

The whole code looked like this:

整个代码如下所示:

<?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" />

This is an all xml solution, to put tint on an ImageView on press or on active. Similar can be done for ImageButton

这是一个全 xml 解决方案,用于在按下或激活时在 ImageView 上着色。ImageButton 也可以这样做

Note that this only works for API level >= 21.

请注意,这仅适用于 API 级别 >= 21。

回答by Henrique de Sousa

Finally I have found a solution for API < 21:

最后我找到了 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));
}

May this help someone not to lose 2 hours !

愿这有助于某人不要失去 2 小时!

回答by ckern

I found a way to do this in xml (in api 21 and up at least).

我找到了一种在 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>

By setting the tint on the bitmap it's possible to reuse the same drawable in xml without having to intercept touches or subclass ImageView or ImageButton.

通过在位图上设置色调,可以在 xml 中重用相同的可绘制对象,而无需拦截触摸或子类 ImageView 或 ImageButton。

Once the selector has been created, just apply that as the src of the ImageView or ImageButton.

创建选择器后,只需将其应用为 ImageView 或 ImageButton 的 src。

回答by Fu-Lung Chen

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

回答by Fu-Lung Chen

You can set color (tint) from xml.

您可以从 xml 设置颜色(色调)。

Set transparent(android:background="@null") for backgroundthen use tint:

设置transparent( android: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" />

回答by Elisha Sterngold

What I'm doing is add a custom button that has the function setColorFilter.

我正在做的是添加一个具有 setColorFilter 函数的自定义按钮。

Like this I can use the new button in the xml.

像这样我可以在 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);
}}

and for the ImageButton

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

回答by aeskreis

I noticed there are some requests here for people wanting to know how to do this in XML. It is actually quite simple. This can be accomplished using a layer-list

我注意到这里有一些要求希望知道如何在 XML 中执行此操作的人。其实很简单。这可以使用layer-list

Your button's drawable (drawable/some_button.xml):

您的按钮可绘制(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>

And this is the highlighted drawable (drawable/some_button_highlighted.xml)

这是突出显示的可绘制对象(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>

Now you can use this in any other xml:

现在您可以在任何其他 xml 中使用它:

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

I hope this helps someone in the future.

我希望这对未来的人有所帮助。

回答by ubuntudroid

As you defined the selector to be the src of the ImageButton Android will AFAIK just take the drawable because that's what matches the type of src. So tint won't be used.

当您将选择器定义为 ImageButton 的 src 时,Android 将 AFAIK 仅采用 drawable,因为它与 src 的类型相匹配。所以不会使用色调。

Nevertheless, I had a similar problem: I also tried to use a selector like yours but for the android:tint value of the ImageButton instead of android:src. Of course I omitted the tint values you have in your selector. This would solve your problem, too, because you want to use the same drawable for all states. Curiously I get a NumberFormatException everytime stating that the system was unable to parse 'res/color/tint_selector.xml' (which is indeed my selector) as integer. To be specific my code looks like this:

尽管如此,我遇到了类似的问题:我也尝试使用像您这样的选择器,但是对于 ImageButton 的 android:tint 值而不是 android:src。当然,我省略了选择器中的色调值。这也可以解决您的问题,因为您希望对所有状态使用相同的可绘制对象。奇怪的是,每次我都收到一个 NumberFormatException ,指出系统无法将“res/color/tint_selector.xml”(这确实是我的选择器)解析为整数。具体来说,我的代码如下所示:

This is my selector, saved in /res/color/tint_selector.xml:

这是我的选择器,保存在 /res/color/tint_selector.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="#D3D3D3"/> <!-- pressed -->
   <item android:color="#ff000000"/> <!-- default -->
</selector>

And this is the corresponding ImageButton:

这是相应的 ImageButton:

<ImageButton android:id="@+id/program_help"
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"
     android:src="@drawable/symbol"
     android:tint="@color/tint_selector">
</ImageButton>

Maybe this helps you a bit although it currently doesn't work.

也许这对您有所帮助,尽管它目前不起作用。