Android imageview更改色调以模拟按钮单击
Posted
技术标签:
【中文标题】Android imageview更改色调以模拟按钮单击【英文标题】:Android imageview change tint to simulate button click 【发布时间】:2012-06-21 03:40:40 【问题描述】:我有一个图像视图,我在其上设置了从 url 获取的位图。 在 imageview 上,我设置了一个 onClickListener,它会打开一个对话框。
我想在按下 imageview 时以某种方式更改色调(使其更暗)以提供一种按钮点击的感觉。
你有什么建议?
【问题讨论】:
【参考方案1】:happydude 的回答是处理这个问题的最优雅的方式,但不幸的是(正如 cmets 中所指出的)ImageView 的源代码只接受一个整数(纯色)。 Issue 18220 已经存在了几年来解决这个问题,我在那里发布了一个解决方法,我将在这里总结一下:
扩展 ImageView 并使用根据新状态设置色调的代码包装 drawableStateChanged():
TintableImageView.java
package com.example.widgets;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.support.v7.widget.AppCompatImageView;
import com.example.R;
public class TintableImageView extends AppCompatImageView
private ColorStateList tint;
public TintableImageView(Context context)
super(context);
public TintableImageView(Context context, AttributeSet attrs)
super(context, attrs);
init(context, attrs, 0);
public TintableImageView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
init(context, attrs, defStyle);
private void init(Context context, AttributeSet attrs, int defStyle)
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TintableImageView, defStyle, 0);
tint = a.getColorStateList(R.styleable.TintableImageView_tintColorStateList);
a.recycle();
@Override
protected void drawableStateChanged()
super.drawableStateChanged();
if (tint != null && tint.isStateful())
updateTintColor();
private void updateTintColor()
int color = tint.getColorForState(getDrawableState(), 0);
setColorFilter(color);
定义一个自定义属性:
attrs.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="TintableImageView">
<attr name="tintColorStateList" format="reference|color" />
</declare-styleable>
</resources>
将小部件和自定义属性与您的本地命名空间一起使用,而不是 Android 的:
example_layout.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:orientation="horizontal">
<com.example.widgets.TintableImageView
android:layout_
android:layout_
android:src="@drawable/example"
android:clickable="true"
app:tintColorStateList="@color/color_selector"/>
</LinearLayout>
然后您可以使用如 happydude 建议的颜色选择器:
color_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="@color/pressed_color"/>
<item android:color="#00000000"/>
</selector>
【讨论】:
我正在尝试您的解决方案,但是当TintableImageView
中的构造函数调用它的超级时仍然得到java.lang.NumberFormatException: Invalid int: "@2130837701"
...我需要通过new int[]R.styleable.TintableImageView_tint
因为obtainStyledAttributes
要求一个数组,并在 colors.xml 中声明 <drawable name="tab_icon_selector">@drawable/tab_icon_selector</drawable>
以便能够从 android:tint 引用它
这就是我的答案在 attrs.xml 中定义自定义色调属性的原因。您必须在布局中使用自定义 app:tint 而不是 android:tint。本质上,您正在创建一个新属性,该属性包装原生属性并一次为其提供一种颜色。
感谢您的回答!我已更改为app:tint
并且异常消失了...但是仍然没有使用选择器,即我的图标一直是黑色的...是我在colors.xml中的可绘制声明正确的方法是吗?
请回答我关于 SO 的问题,以便我接受 ***.com/questions/19500039/…
我粘贴了您的代码并检查了所有内容,但它不起作用。【参考方案2】:
一种方法是使用ColorFilter
和ColorStateList
的组合,其中包含按下按钮时的色调颜色。 res/color 目录中ColorStateList
的 xml 如下所示:
button_pressed.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="@color/pressed_color"/>
<item android:color="#00000000"/>
</selector>
@color/pressed_color
是您的色调(应该是部分透明的)。然后在 ImageView
子类中,通过覆盖 drawableStateChanged()
来应用颜色。
@Override
protected void drawableStateChanged()
super.drawableStateChanged();
ColorStateList list = getResources().getColorStateList(R.color.button_pressed);
int color = list.getColorForState(getDrawableState(), Color.TRANSPARENT);
setColorFilter(color);
invalidate();
每当按钮的状态发生变化时,都会调用此代码并根据需要自动设置色调。
【讨论】:
我尝试了你的建议。它似乎没有做任何事情。使用调试器我注意到 drawableStateChanged() 方法没有在 onPress 上触发,但似乎只在 onClick 上触发。 嗯,我在上面的代码中看不到任何错误。根据定义,当按下状态发生变化时,应该调用该方法。我一直在我自己的代码中使用这个结构,它工作正常。作为测试,在您的 ImageView XML 中添加android:tint="@color/pressed_color"
。这应该为您的图像添加永久色调,因为它调用与上述代码相同的颜色过滤器设置方法。这样你至少可以排除你选择的颜色有问题。
对不起,我很笨。您可以直接将您的颜色状态列表添加到您的ImageView
XML 文件中。请参阅上面的编辑。
好的。所以这是当我设置 android:tint="@drawable/button_pressed" 时出现的错误,我在编译期间收到此错误,06-19 20:22:54.222: E/AndroidRuntime(2338): Caused by: java. lang.NumberFormatException:无法将“res/drawable/button_pressed.xml”解析为整数 06-19 20:22:54.222: E/AndroidRuntime(2338): at java.lang.Integer.parse(Integer.java:383) 06 -19 20:22:54.222: E/AndroidRuntime(2338): 在 java.lang.Integer.parseInt(Integer.java:372) 06-19 20:22:54.222: E/AndroidRuntime(2338): 在 com.android .internal.util.XmlUtils.convertValueToInt(XmlUtils.java:12s)
首先,请忽略“编辑”。我查看了源代码,果然tint
只接受纯色。很抱歉让你走错了路。其次,我在我创建的自定义ImageView
中尝试了上面原始帖子中的代码,它对我有用。我通过使用setImageResource(int)
设置图像对其进行了测试,但我不明白为什么其他图像设置方法不起作用。最后,确保在您的 XML 定义中添加android:clickable="true"
。如果没有这条线,它将无法工作。【参考方案3】:
我必须对其进行测试,但您应该能够将具有该行为的 xml 设置为 ImageView 可绘制对象,然后将您的位图设置为 ImageView 背景。
【讨论】:
【参考方案4】:对我来说,一个简单的解决方案是有效的,在 onClick 事件中使用 setAlpha(180) 会使图像变暗,给用户一个点击或触摸的反馈。
final ImageView myImage = (ImageView) findViewById(R.id.ivDocument);
myImage.setImage...(... your image ...); // load your ImageView
myImage.setClickable(true);
myImage.setFocusable(true);
myImage.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
myImage.setAlpha(180);
doWhateverYouWantHere(v);
);
关于你的 XML 布局,没什么特别的。
【讨论】:
【参考方案5】:这段代码 sn-p 为我工作:
porterDuffColorFilter = newPorterDuffColorFilter(getResources().getColor(R.color.cardview_dark_background),PorterDuff.Mode.MULTIPLY);
imgView.getDrawable().setColorFilter(porterDuffColorFilter);
imgView.setBackgroundColor(Color.TRANSPARENT);
【讨论】:
以上是关于Android imageview更改色调以模拟按钮单击的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 中以编程方式更改 ImageView 的图像
更改 Java Android Widget 中 ImageView 的 xml 值 android:layout_marginStart