Android imageview 更改色调以模拟按钮单击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11095222/
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
Android imageview change tint to simulate button click
提问by Abhishek
I have an imageview on which I have set a bitmap fetched from an url. On the imageview I have set an onClickListener which opens up a dialog.
我有一个图像视图,我在其上设置了从 url 获取的位图。在 imageview 上,我设置了一个 onClickListener 来打开一个对话框。
I want to somehow change the tint (make it darker) when the imageview is pressed upon to provide a sort of button click like feel.
当按下图像视图以提供一种类似按钮点击的感觉时,我想以某种方式改变色调(使其变暗)。
What do you suggest?
你有什么建议?
回答by Stephen Kidson
happydude's answer is the most elegant way to handle this but unfortunately (as pointed out in the comments) the source code for ImageView only accepts an integer (solid colour). Issue 18220has been around for a couple years addressing this, I've posted a workaround there that I'll summarize here:
happydude 的答案是处理这个问题的最优雅的方法,但不幸的是(如评论中所指出的)ImageView 的源代码只接受一个整数(纯色)。问题 18220已经存在几年了,我已经在那里发布了一个解决方法,我将在此处进行总结:
Extend ImageView and wrap drawableStateChanged() with code that sets the tint based on the new state:
扩展 ImageView 并使用基于新状态设置色调的代码包装 drawableStateChanged():
TintableImageView.java
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);
}
}
Define a custom attribute:
定义自定义属性:
attrs.xml
属性文件
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="TintableImageView">
<attr name="tintColorStateList" format="reference|color" />
</declare-styleable>
</resources>
Use the widget and custom attribute with your local namespace instead of Android's:
将小部件和自定义属性与您的本地命名空间一起使用,而不是 Android 的:
example_layout.xml
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>
You can then use a colour selector like happydude suggested:
然后你可以使用像happydude建议的颜色选择器:
color_selector.xml
颜色选择器.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>
回答by happydude
One way would be to use a combination of a ColorFilter
and a ColorStateList
that contains your tint color for when the button is pressed. The xml for the ColorStateList
in the res/color directory would look like this:
一种方法是使用 aColorFilter
和 a的组合,ColorStateList
其中包含按下按钮时的色调。ColorStateList
res/color 目录中的 xml如下所示:
button_pressed.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>
where @color/pressed_color
is your tint color (which should be partially transparent). Then in your ImageView
subclass, you apply the color by overriding drawableStateChanged()
.
@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();
}
Any time the button's state changes, this code is called and will automatically set the tint as appropriate.
每当按钮的状态发生变化时,都会调用此代码并根据需要自动设置色调。
回答by Jagoliveira
For me a simple solution is working, using setAlpha(180)in onClickevent make the image darker, giving the user a feedback that it was clicked or touched.
对我来说,一个简单的解决方案是有效的,在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);
}
});
Regarding your XML layout, nothing special.
关于您的 XML 布局,没什么特别的。
回答by Charlie-Blake
I'd have to test it out, but you should be able to set an xml with that behaviour as the ImageView drawable, and then set your bitmap as the ImageView background.
我必须对其进行测试,但您应该能够将具有该行为的 xml 设置为 ImageView 可绘制对象,然后将您的位图设置为 ImageView 背景。
回答by Mehatab
This code snippet worked for me:
此代码片段对我有用:
porterDuffColorFilter = newPorterDuffColorFilter(getResources().getColor(R.color.cardview_dark_background),PorterDuff.Mode.MULTIPLY);
imgView.getDrawable().setColorFilter(porterDuffColorFilter);
imgView.setBackgroundColor(Color.TRANSPARENT);