我有一个ImageView,在其中设置了从URL获取的位图。在ImageView上,我设置了一个onClickListener来打开一个对话框。
当点击ImageView时,我想要改变它的色调(使其更暗),以提供一种类似于按钮点击的感觉。
你有什么建议?
我有一个ImageView,在其中设置了从URL获取的位图。在ImageView上,我设置了一个onClickListener来打开一个对话框。
当点击ImageView时,我想要改变它的色调(使其更暗),以提供一种类似于按钮点击的感觉。
你有什么建议?
happydude的回答是处理这个问题最优雅的方式,但不幸的是(正如评论中指出的),ImageView的源代码只接受整数(纯色)。Issue 18220已经存在了几年,解决了这个问题,我在那里发布了一个解决方法,在此做个总结:
扩展ImageView并包装drawableStateChanged(),使用代码根据新状态设置tint:
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>
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_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.example.widgets.TintableImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/example"
android:clickable="true"
app:tintColorStateList="@color/color_selector"/>
</LinearLayout>
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>
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();
}
android:tint="@color/pressed_color"
。 这应该会给您的图像添加一个永久的色调,因为它调用与上面代码相同的colorfilter设置方法。 这样,您至少可以排除您选择的颜色有问题的可能性。 - happydudeImageView
XML文件中。请参见上面的编辑。 - happydudetint
只接受纯色。很抱歉让你走错了方向。第二,在我创建的自定义ImageView
中尝试了上面原始帖子中的代码,它对我有效。我通过使用setImageResource(int)
来设置图像进行了测试,虽然我不明白为什么其他图像设置方法不能工作。最后,请确保在XML定义中添加android:clickable="true"
。如果没有这一行,它将无法正常工作。 - happydude我得测试一下,但你应该能够将一个具有此行为的xml设置为ImageView drawable,然后将你的位图设置为ImageView背景。
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);
}
});
这段代码片段对我有效:
porterDuffColorFilter = newPorterDuffColorFilter(getResources().getColor(R.color.cardview_dark_background),PorterDuff.Mode.MULTIPLY);
imgView.getDrawable().setColorFilter(porterDuffColorFilter);
imgView.setBackgroundColor(Color.TRANSPARENT);
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引用它。 - Lucas Jota