2012-06-19 36 views
35

我有一個imageview,我已經設置了從url中獲取的位圖。 在imageview上,我設置了一個打開對話框的onClickListener。Android的imageview更改色調模擬按鈕點擊

我想以某種方式改變顏色(使其更深),當按下圖像視圖時,提供一種像感覺一樣的按鈕點擊。

你有什麼建議?

回答

0

我不得不對它進行測試,但您應該能夠將該行爲設置爲ImageView drawable,然後將您的位圖設置爲ImageView背景。

6

一種方法是使用ColorFilterColorStateList的組合,其中包含您按下按鈕時的色調顏色。在res /彩色目錄爲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(); 
} 

無論何時按鈕的狀態發生變化,此代碼被調用並會自動設置適當的色調。

+0

我嘗試了你的建議。它似乎沒有做任何事情。使用調試器,我發現drawableStateChanged()方法在onPress上沒有觸發,但似乎只在onClick上觸發。 – Abhishek

+0

嗯,我在上面的代碼中看不到任何錯誤。根據定義,該方法應該在按下狀態改變時調用。我一直在我自己的代碼中使用這個構造,它工作正常。作爲一個測試,在你的ImageView XML中添加'android:tint =「@ color/pressed _color_」「。這應該爲圖像添加永久性色調,因爲它與上面的代碼調用相同的colorfilter設置方法。這樣,您至少可以排除您選擇顏色的問題。 – happydude

+0

對不起,我很笨。你可以直接將你的顏色狀態列表直接添加到你的'ImageView' XML文件中。見上面的編輯。 – happydude

0

對我來說,一個簡單的解決方案正在使用setAlpha(180)的onClick事件使圖像變暗,給用戶一個反饋,它被點擊或觸摸。

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佈局,沒有什麼特別的。

88

happydude的答案是處理這個問題的最優雅的方式,但不幸的是(正如在評論中指出的那樣)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> 

使用Widget和自定義屬性與您當地的命名空間,而不是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_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> 

然後,您可以使用顏色選擇像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> 
+2

我想你的解決方案,但仍然得到'java.lang.NumberFormatException:無效的int:「@ 2130837701」'當TintableImageView'內的構造函數調用它的超級...我需要傳遞'new int [] {R .styleable.TintableImageView_tint}'因爲'obtainStyledAttributes'需要一個數組,並聲明' @ drawable/tab_icon_selector'inside colors.xml以便能夠從android:tint中引用它 –

+3

這就是爲什麼我的答案在attrs.xml中定義了一個自定義tint屬性。您必須在您的佈局中使用自定義**應用程序:tint **而不是** android:tint **。實質上,您正在創建一個新的屬性,該屬性包裝原生屬性並一次爲其提供一種顏色。 –

+0

感謝您的回答!我已經更改爲'app:tint',並且異常消失了...但是選擇器仍然沒有被使用,即我的圖標始終是黑色的... ...是我在colors.xml中的可繪製聲明的正確方法去做吧? –

-1

這段代碼爲我工作:

porterDuffColorFilter = newPorterDuffColorFilter(getResources().getColor(R.color.cardview_dark_background),PorterDuff.Mode.MULTIPLY); 

imgView.getDrawable().setColorFilter(porterDuffColorFilter); 
imgView.setBackgroundColor(Color.TRANSPARENT);