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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:58:50  来源:igfitidea点击:

Android imageview change tint to simulate button click

androidandroid-imageviewandroid-ui

提问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 ColorFilterand a ColorStateListthat contains your tint color for when the button is pressed. The xml for the ColorStateListin the res/color directory would look like this:

一种方法是使用 aColorFilter和 a的组合,ColorStateList其中包含按下按钮时的色调。ColorStateListres/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_coloris your tint color (which should be partially transparent). Then in your ImageViewsubclass, 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);