2010-06-11 8 views
49

Ho un ImageButton nella mia app e ho bisogno di cambiare la tonalità dell'immagine quando il pulsante è pressed/focused. Ho il ImageButton insieme per ottenere il suo src da un file XML, che come segue:Come modificare la tonalità di un ImageButton sullo stato attivo/premere

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <!-- pressed --> 
    <item 
     android:state_pressed="true" 
     android:tint="@color/black" 
     android:drawable="@drawable/search" 
     /> 

    <!-- focused --> 
    <item 
     android:state_focused="true" 
     android:tint="@color/black" 
     android:drawable="@drawable/search" 
     /> 

    <!-- default --> 
    <item 
     android:tint="@null" 
     android:drawable="@drawable/search" 
     /> 

</selector> 

Tuttavia la tinta non si applica quando il ImageButton viene premuto o focalizzata - l'immagine mostra altrettanto normale. Il colore nero è definito come #000000 come sempre. Qualche idea?

+4

Ciao. Mi stavo chiedendo se finalmente hai trovato un modo XML per risolvere questo. Grazie in anticipo. –

risposta

70

È possibile modificare la tinta, abbastanza facilmente in codice tramite:

ImageButton button = (ImageButton) this.findViewById(R.id.button_i_want_to_modify); 
button.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint 

Speranza che aiuta.

JS

+8

Funziona. Ma mi piacerebbe farlo via XML, se possibile (scusatemi pignoli). –

+0

Controlla la risposta su http://stackoverflow.com/questions/19500039/how-to-use-selector-to-tint-imageview-in-android – asiby

+0

Oppure utilizza l'associazione dati. – ubuntudroid

-2

Come è stato definito il selettore di essere lo src del ImageButton Android sarà AFAIK basta prendere la drawable perché è quello che corrisponde al tipo di src. Quindi la tinta non sarà usata.

Tuttavia, ho avuto un problema simile: ho anche provato a utilizzare un selettore come il tuo ma per l'androide: valore tint di ImageButton anziché Android: src. Ovviamente ho omesso i valori di tinta che hai nel tuo selettore. Questo risolverebbe anche il tuo problema, perché vuoi usare lo stesso drawable per tutti gli stati. Curiosamente ottengo una NumberFormatException ogni volta affermando che il sistema non è stato in grado di analizzare 'res/color/tint_selector.xml' (che in effetti è il mio selettore) come numero intero. Per essere precisi il mio codice è simile al seguente:

Questo è il mio selettore, salvato in /res/color/tint_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="#D3D3D3"/> <!-- pressed --> 
    <item android:color="#ff000000"/> <!-- default --> 
</selector> 

e questo è il corrispondente ImageButton:

<ImageButton android:id="@+id/program_help" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:src="@drawable/symbol" 
    android:tint="@color/tint_selector"> 
</ImageButton> 

Forse questo ti aiuta un po 'anche se al momento non funziona.

+0

È compatibile con API meno di 21? – JHowzer

1

Quello che sto facendo è aggiungere un pulsante personalizzato che abbia la funzione setColorFilter.

In questo modo posso utilizzare il nuovo pulsante in xml.

public class CustomButton extends Button { 

public CustomButton(Context context) { 
    super(context); 
} 

public CustomButton(Context context, AttributeSet attributes) { 
    super(context, attributes); 
}; 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    int maskedAction = event.getActionMasked(); 
    if (maskedAction == MotionEvent.ACTION_DOWN) 
     getBackground().setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN); 
    else if (maskedAction == MotionEvent.ACTION_UP) 
     getBackground().setColorFilter(null); 
    return super.onTouchEvent(event); 
}} 

e per l'ImageButton

public class CustomImageButton extends ImageButton { 

public CustomImageButton(Context context) { 
    super(context); 
} 

public CustomImageButton(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    int maskedAction = event.getActionMasked(); 
    if (maskedAction == MotionEvent.ACTION_DOWN) 
     setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN); 
    else if (maskedAction == MotionEvent.ACTION_UP) 
     setColorFilter(null); 
    return super.onTouchEvent(event); 
}} 
1

ho notato che ci sono alcune richieste qui per persone che vogliono sapere come fare questo in XML. In realtà è abbastanza semplice. Ciò può essere realizzato utilizzando un layer-list

del tuo pulsante drawable (drawable/some_button.xml):

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="true" android:drawable="@drawable/some_button_highlighted" /> 
    <item android:drawable="@drawable/some_button_image" /> 
</selector> 

e questa è la evidenziato drawable (drawable/some_button_highlighted.xml)

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="@drawable/some_button_image"/> 
    <item> 
     <shape> 
      <solid android:color="@color/highlighted_button_color" /> 
     </shape> 
    </item> 
</layer-list> 

Ora è possibile utilizzare questo in qualsiasi altro xml:

... 
android:drawable="@drawable/some_button" 
... 

Spero che questo aiuta qualcuno in futuro.

+3

Questo semplicemente disegna un quadrato solido sopra il drawable, se ci fosse un modo per far sì che il secondo layer utilizzi il livello precedente come maschera alfa, allora sarebbe bello – darnmason

2
bt.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
         bt.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint 
         return true; // if you want to handle the touch event 
        case MotionEvent.ACTION_UP: 
         bt.clearColorFilter(); // White Tint 
         return true; // if you want to handle the touch event 
       } 
       return false; 
      } 
     }); 
5

Finalmente ho trovare la soluzione per l'API < 21:

Button more = (Button) findViewById(R.id.more); 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
    more.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN); 
} else { 
    Drawable wrapDrawable = DrawableCompat.wrap(more.getBackground()); 
    DrawableCompat.setTint(wrapDrawable, color)); 
    more.setBackgroundDrawable(DrawableCompat.unwrap(wrapDrawable)); 
} 

Possa questo aiuto a qualcuno di non perdere 2 ore!

+0

se stai usando drawablecompat dovresti essere in grado di usarlo su versioni API inferiori senza problemi – dabluck

+0

Stavo usando un normale pulsante con un layout XML personalizzato. DrawableCompat è stata l'unica soluzione fino ad oggi che funziona su pre-API 21. –

4

Ho trovato un modo per farlo in xml (in api 21 e fino almeno).

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="true" > 
     <bitmap 
      android:src="@drawable/search" 
      android:tint="@color/black" 
      /> 
    </item> 
    <item android:drawable="@drawable/search"/> 
</selector> 

Impostando la tinta sulla bitmap è possibile riutilizzare lo stesso drawable in XML senza dover intercettare tocca o sottoclasse ImageView o ImageButton.

Una volta creato il selettore, è sufficiente applicarlo come src di ImageView o ImageButton.

+0

Bella cattura! si noti che l'attributo di tinta sull'elemento bitmap prima dell'API 21 non farà nulla -> https://code.google.com/p/android/issues/detail?id=78461 – Gomino

0

È possibile impostare il colore (tinta) da xml.

Set transparent (android:background="@null") per background quindi utilizzare tint:

<ImageButton 
    android:layout_width="wrap_content" 
    android:layout_height="fill_parent" 
    android:tint="@color/Amber_200" 
    android:background="@null" 
    android:src="@drawable/back_selector" /> 
1

Ecco come lo ha fatto utilizzando solo xml. Nella cartella estraibile crea un selettore. Ad esempio: touch_selector.xml

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <!-- State when a row is being pressed, but hasn't yet been activated (finger down) --> 
    <item android:state_pressed="true" android:color="@color/semi_slate" /> 

    <!-- When the view is "activated". In SINGLE_CHOICE_MODE, it flags the active row 
    of a ListView --> 
    <item android:state_activated="true" android:color="@color/semi_slate" /> 

    <!-- Default, "just hangin' out" state. --> 
    <item android:color="@android:color/transparent" /> 
</selector> 

A mio avviso Immagine in XML ho impostato l'attributo android: tinta al drawable creato in precedenza.

android:tint = "@drawable/touch_selector" 

L'intero codice si presentava così:

<?xml version="1.0" encoding="utf-8"?> 
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/poster" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:adjustViewBounds="true" 
android:scaleType="centerCrop" 
android:tint="@drawable/touch_selector" /> 

Questo è un all soluzione XML, a mettere su una tinta ImageView sulla stampa o sui attiva. Simile può essere fatto per ImageButton

Problemi correlati