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
How do I change the tint of an ImageButton on focus/press
提问by Joseph Earl
I have an ImageButton
in my app and I need to change the tint of the image when the button is pressed/focused
. I have the ImageButton
set to get its src
from 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 ImageButton
is pressed or focused - the image just displays as normal. The color black is defined as #000000
as 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 background
then 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.
也许这对您有所帮助,尽管它目前不起作用。