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

时间:2010-06-11 17:45:44

标签: android image selector imagebutton tint

我的应用中有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。有什么想法吗?

10 个答案:

答案 0 :(得分:86)

您可以通过以下方式轻松更改色调:

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

希望它有所帮助。

JS

答案 1 :(得分:14)

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

在我的xml图像视图中,我将android:tint属性设置为上面创建的drawable。

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级别&gt; = 21.

答案 2 :(得分:7)

我找到了一种在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中重复使用相同的drawable,而不必截取触摸或子类ImageView或ImageButton。

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

答案 3 :(得分:6)

最后,我找到了一个API&lt;的解决方案。 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个小时!

答案 4 :(得分:2)

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

答案 5 :(得分: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);
}}

答案 6 :(得分:1)

我注意到这里有一些请求想要知道如何在XML中执行此操作的人。它实际上非常简单。这可以使用layer-list

来完成

你的按钮的drawable(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(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"
...

我希望这有助于将来的某些人。

答案 7 :(得分:0)

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

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

答案 8 :(得分: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
        }

对我有用。

答案 9 :(得分:-3)

当您将选择器定义为ImageButton的src时,AFAIK只会采用drawable,因为这与src的类型相匹配。因此不会使用色调。

然而,我遇到了类似的问题:我也尝试使用像你这样的选择器,但是对于ImageButton的android:tint值而不是android:src。当然,我省略了选择器中的色调值。这也可以解决您的问题,因为您希望对所有状态使用相同的drawable。奇怪的是我每次都会得到一个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>

这可能对你有所帮助,虽然它目前无效。