66

我的应用程序中有一个ImageButton,当按钮为 时,我需要更改图像的色调pressed/focused。我ImageButton有一套从 XML 文件中获取它的设置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一如既往地定义黑色。有任何想法吗?

4

10 回答 10

107

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

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

希望能帮助到你。

JS

于 2010-08-09T19:10:18.547 回答
23

以下是仅使用 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" />

这是一个全 xml 解决方案,可以在按下或激活时对 ImageView 进行着色。可以对 ImageButton 进行类似的操作

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

于 2016-12-21T20:47:45.653 回答
11

最后我找到了 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 个小时!

于 2015-11-20T18:47:45.213 回答
8

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

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

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

于 2016-07-07T19:22:19.100 回答
3
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;
            }
        });
于 2015-04-15T06:49:51.040 回答
1

我正在做的是添加一个具有 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);
}}
于 2013-12-24T14:03:06.860 回答
1

我注意到这里有一些要求人们想知道如何在 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"
...

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

于 2014-06-23T19:30:07.253 回答
1

您可以从 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" />
于 2016-08-29T05:09:12.917 回答
0

我有同样的问题,我找到了这个解决方案:

logoImage.setOnTouchListener { v, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                if (logoImage.isSelected) {
                    logoImage.setColorFilter(context.getColor(R.color.blue_unselect), PorterDuff.Mode.SRC_IN)
                } else {
                    logoImage.setColorFilter(null)
                }
            } else if (event.action == MotionEvent.ACTION_UP) {
                if (!logoImage.isSelected) {
                    logoImage.setColorFilter(null)
                } else {
                    logoImage.setColorFilter(context.getColor(R.color.blue_unselect), PorterDuff.Mode.SRC_IN)
                }
            } else if (event.action == MotionEvent.ACTION_CANCEL) {
                if (root.isSelected) {
                    logoImage.setColorFilter(null)
                } else {
                    logoImage.setColorFilter(context.getColor(R.color.blue_unselect), PorterDuff.Mode.SRC_IN)
                }
            }
            false
        }

它对我有用。

于 2020-10-14T08:45:19.903 回答
-3

当您将选择器定义为 ImageButton 的 src 时,AFAIK 将只采用可绘制对象,因为这与 src 的类型相匹配。所以不会使用色调。

尽管如此,我也遇到了类似的问题:我也尝试使用像你这样的选择器,但是对于 ImageButton 的 android:tint 值而不是 android:src。当然,我省略了您在选择器中的色调值。这也可以解决您的问题,因为您想对所有状态使用相同的可绘制对象。奇怪的是,我每次都得到一个 NumberFormatException ,指出系统无法将“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>

这是相应的 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>

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

于 2010-08-25T17:15:27.360 回答