2012-06-19 8 views

Odpowiedz

0

musiałbym przetestować go, ale powinieneś być w stanie ustawić xml z tego zachowania jako rozciągliwej ImageView, a następnie ustawić bitmapę jako tło ImageView.

6

Jedną z metod jest użycie kombinacji ColorFilter i ColorStateList, która zawiera kolory odcień po naciśnięciu przycisku. Xml dla ColorStateList w katalogu res/kolor będzie wyglądać następująco:

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> 

gdzie @color/pressed_color jest twój kolor odcień (który powinien być częściowo przezroczysta). Następnie w podklasie ImageView zastosujesz kolor, przesłoniwszy 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(); 
} 

Za każdym razem, gdy zmienia się stan przycisku, ten kod jest wywoływany i automatycznie ustawi odcień w zależności od potrzeb.

+0

I wypróbowałem twoją sugestię. Wydaje się, że nic nie robi. Używając debuggera zauważyłem, że metoda drawableStateChanged() nie jest wyzwalana w onPress, ale wydaje się, że wyzwala tylko onClick. – Abhishek

+0

Hmm, nie widzę żadnych błędów w powyższym kodzie. Z definicji metoda powinna zostać wywołana, gdy wciśnięty stan ulegnie zmianie. Używam tej konstrukcji w moim własnym kodzie i działa dobrze. Jako test, w swoim ImageView XML dodaj 'android: tint =" @ color/pressed_color "'. Powinno to dodać trwały odcień do obrazu, ponieważ wywołuje tę samą metodę ustawiania filtra koloru jak powyższy kod. W ten sposób możesz przynajmniej wykluczyć problem z wybranym kolorem. – happydude

+0

Przepraszam, jestem głupi. Możesz bezpośrednio dodać swoją listę stanów kolorów bezpośrednio do pliku XML 'ImageView' bezpośrednio. Zobacz edycję powyżej. – happydude

0

Dla mnie to proste rozwiązanie działa, używając setAlpha (180) w onClick wydarzenia sprawiają, że obraz ciemniejszy, dając użytkownikowi informacji zwrotnej, że została ona kliknięcia lub dotknięcia.

Jeśli chodzi o układ XML, nic specjalnego. Odpowiedź

88

happydude jest najbardziej elegancki sposób, aby sobie z tym poradzić, ale niestety (jak wskazano w komentarzach) kod źródłowy ImageView akceptuje tylko liczbę całkowitą (Solid Color). Issue 18220 już od paru lat adresowania tego, jakie napisali obejście tam, że będę streszczać tutaj:

Extend ImageView i owinąć drawableStateChanged() z kodem, który ustawia odcień na podstawie nowego stanu:

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); 
    } 

} 

zdefiniować atrybut niestandardowy:

attrs.xml

<?xml version="1.0" encoding="UTF-8"?> 
<resources> 

    <declare-styleable name="TintableImageView"> 
     <attr name="tintColorStateList" format="reference|color" /> 
    </declare-styleable> 

</resources> 

Użyj widget i atrybut niestandardowy z lokalnej przestrzeni nazw zamiast Androida:

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> 

Następnie można użyć selektora kolorów jak happydude zasugerował:

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

Próbuję twojego rozwiązania, ale wciąż otrzymuję 'java.lang.NumberFormatException: Invalid int:" @ 2130837701 "' gdy konstruktor wewnątrz 'TintableImageView' nazywa jego super ... Musiałem przekazać' nowy int [] {R .styleable.TintableImageView_tint} 'ponieważ' obtainStyledAttributes' pytał o tablicę i zadeklarował ' @ drawable/tab_icon_selector' inside colors.xml, aby móc odnieść się do niego z androida: odcień –

+3

Dlatego moja odpowiedź definiuje niestandardowy atrybut tinty w attrs.xml. Musisz użyć niestandardowej ** aplikacji: odcień ** w swoim układzie zamiast ** android: odcień **. Zasadniczo tworzysz nowy atrybut, który otacza natywny i podaje go po jednym kolorze na raz. –

+0

dzięki za odpowiedź! Zmieniłem na 'app: tint' i wyjątek zniknął ... Ale selektor nadal nie jest używany, tzn. Moje ikony są czarne cały czas ... to moja deklaracja do rysowania wewnątrz colors.xml we właściwy sposób to zrobić? –

-1

Ten fragment kodu pracował dla mnie:

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

imgView.getDrawable().setColorFilter(porterDuffColorFilter); 
imgView.setBackgroundColor(Color.TRANSPARENT); 
Powiązane problemy