如何在焦点/按下时更改 ImageButton 的色调
Posted
技术标签:
【中文标题】如何在焦点/按下时更改 ImageButton 的色调【英文标题】:How do I change the tint of an ImageButton on focus/press 【发布时间】:2011-03-02 18:50:21 【问题描述】:我的应用中有一个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
。有什么想法吗?
【问题讨论】:
你好。我想知道您是否最终找到了解决此问题的 XML 方法。提前致谢。 【参考方案1】:您可以通过以下方式在代码中轻松更改色调:
ImageButton button = (ImageButton) this.findViewById(R.id.button_i_want_to_modify);
button.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
希望对你有帮助。
JS
【讨论】:
有效。但如果可能的话,我想通过 XML 来实现(抱歉挑剔)。 在***.com/questions/19500039/…查看答案 或者使用数据绑定。 添加android:tint="@color/myColor"
对我有用。【参考方案2】:
这是仅使用 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_
android:layout_
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:tint="@drawable/touch_selector" />
这是一个全 xml 解决方案,用于在按下或激活时在 ImageView 上添加色调。 ImageButton 也可以这样做
请注意,这仅适用于 API 级别 >= 21。
【讨论】:
您也可以将其用于低于 21 的 API 与 app:tint。 不知道怎么回事。设置此色调后,imageView 将在正常状态下变为透明...【参考方案3】:我终于找到了 API
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 个小时!
【讨论】:
如果您使用的是 drawablecompat,您应该可以在较低的 API 版本上使用它而不会出现问题 我使用的是带有自定义 XML 布局的普通按钮。 DrawableCompat 是迄今为止唯一适用于 pre-API 21 的修复程序。 另见我在***.com/questions/31021823/… 的其他答案,了解 DrawableCompat 在 API 21 之前的使用情况。【参考方案4】:我找到了一种在 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。
【讨论】:
不错的收获!请注意,API 21 之前的位图元素上的 tint 属性将不起作用 -> code.google.com/p/android/issues/detail?id=78461 仅供参考,如果您的可绘制对象是 xml 格式,这将不起作用。在这种情况下使用<shape />
而不是<bitmap />
。【参考方案5】:
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;
);
【讨论】:
【参考方案6】:我正在做的是添加一个具有 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);
【讨论】:
【参考方案7】:我注意到这里有一些希望了解如何在 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 (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"
...
我希望这对将来的某人有所帮助。
【讨论】:
这只是在可绘制对象上绘制一个实心正方形,如果有办法让第二层使用前一层作为 alpha 蒙版,那么这会很酷【参考方案8】:您可以从 xml 设置颜色(色调)。
将transparent
(android:background="@null"
) 设置为background
,然后使用tint
:
<ImageButton
android:layout_
android:layout_
android:tint="@color/Amber_200"
android:background="@null"
android:src="@drawable/back_selector" />
【讨论】:
【参考方案9】:我有同样的问题,我找到了这个解决方案:
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
它对我有用。
【讨论】:
【参考方案10】:当您将选择器定义为 ImageButton 的 src 时,Android 将 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_
android:layout_
android:src="@drawable/symbol"
android:tint="@color/tint_selector">
</ImageButton>
也许这对你有点帮助,虽然它目前不起作用。
【讨论】:
这是否兼容小于 21 的 API?以上是关于如何在焦点/按下时更改 ImageButton 的色调的主要内容,如果未能解决你的问题,请参考以下文章