Domanda

Mi piacerebbe cambiare il colore di un pulsante standard di Android un po 'al fine di corrispondere meglio il marchio del cliente.

Il modo migliore che ho trovato a fare questo fino ad ora è quello di cambiare drawable del Button alla drawable situato in res/drawable/red_button.xml:

<?xml version="1.0" encoding="utf-8"?>    
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/red_button_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/red_button_focus" />
    <item android:drawable="@drawable/red_button_rest" />
</selector>

Ma fare che richiede che io in realtà creare tre drawable differenti per ogni tasto che voglio personalizzare (uno per il pulsante a riposo, uno quando concentrata, e uno quando viene premuto). Che sembra più complicato e non-DRY di cui ho bisogno.

Tutto quello che veramente voglio fare è applicare una sorta di trasformazione del colore al pulsante. C'è un modo più semplice per andare su come cambiare il colore di un pulsante di quello che sto facendo?

È stato utile?

Soluzione

ho scoperto che questo può essere fatto in un unico file abbastanza facilmente. Mettere qualcosa come il seguente codice in un file chiamato custom_button.xml e quindi impostare background="@drawable/custom_button" in vista pulsante:

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

    <item android:state_pressed="true" >
        <shape>
            <gradient
                android:startColor="@color/yellow1"
                android:endColor="@color/yellow2"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <gradient
                android:endColor="@color/orange4"
                android:startColor="@color/orange5"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item>        
        <shape>
            <gradient
                android:endColor="@color/blue2"
                android:startColor="@color/blue25"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

Altri suggerimenti

A seguito di risposta di Tomasz, è anche possibile impostare a livello di codice l'ombra del pulsante dell'intero utilizzando la modalità moltiplicano PorterDuff. Questo cambierà il colore del pulsante piuttosto che solo la tinta.

Se si inizia con un pulsante ombreggiata grigia di serie:

button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

vi darà un pulsante rosso ombreggiato,

button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

vi darà un pulsante verde ombreggiato, ecc, dove il primo valore è il colore in formato esadecimale.

Funziona moltiplicando il valore del colore pulsante di corrente dal valore di colore. Sono sicuro che c'è anche molto di più si può fare con queste modalità.

Mike, potreste essere interessati a filtri colorati.

Un esempio:

button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));

provare questo per ottenere il colore desiderato.

Questa è la mia soluzione che funziona perfettamente partenza da API 15 . Questa soluzione mantiene tutti gli effetti click del pulsante di default, come materiale RippleEffect. Non ho ancora testato su API più bassi, ma dovrebbe funzionare.

Tutto quello che devi fare, è:

1) Creare uno stile che cambia solo colorAccent:

<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
    <item name="colorAccent">@color/com_facebook_blue</item>
</style>
  

Mi consiglia di utilizzare ThemeOverlay.AppCompat o il vostro AppTheme principale, come genitore, per mantenere il resto dei vostri stili.

2) Aggiungere queste due righe al widget di button:

style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"
  

A volte il vostro nuovo colorAccent non è visualizzato in Android Studio Anteprima, ma quando si avvia la tua applicazione sul telefono cellulare, il colore sarà cambiato.


widget di pulsante Esempio

<Button
    android:id="@+id/sign_in_with_facebook"
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/sign_in_facebook"
    android:textColor="@android:color/white"
    android:theme="@style/Facebook.Button" />

 Button campione con colore personalizzato

È ora possibile utilizzare anche di AppCompatButton con l'attributo backgroundTint:

<android.support.v7.widget.AppCompatButton
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:backgroundTint="#ffaa00"/>

Mi piace il suggerimento filtro colore nelle risposte precedenti da @conjugatedirection e @Tomasz; Tuttavia, ho scoperto che il codice fornito finora non è stato applicato facilmente come mi aspettavo.

In primo luogo, non è stato menzionato dove per applicare e cancellare il filtro colore. E 'possibile che ci siano altri posti buoni per fare questo, ma quello che è venuto in mente per me è stato un OnTouchListener .

Dalla mia lettura della domanda iniziale, la soluzione ideale sarebbe quella che non comporta alcuna immagine. La risposta accettata utilizzando custom_button.xml da @emmby è probabilmente una misura migliore di filtri di colore se questo è il vostro obiettivo. Nel mio caso, sto iniziando con un'immagine PNG da un designer dell'interfaccia utente di quello che si suppone che il tasto per assomigliare. Se ho impostato il pulsante di sfondo a questa immagine, le valutazioni evidenziazione di default si perde completamente. Questo codice sostituisce che il comportamento con un effetto di oscuramento programmatico.

button.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 0x6D6D6D sets how much to darken - tweak as desired
                setColorFilter(v, 0x6D6D6D);
                break;
            // remove the filter when moving off the button
            // the same way a selector implementation would 
            case MotionEvent.ACTION_MOVE:
                Rect r = new Rect();
                v.getLocalVisibleRect(r);
                if (!r.contains((int) event.getX(), (int) event.getY())) {
                    setColorFilter(v, null);
                }
                break;
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                setColorFilter(v, null);
                break;
        }
        return false;
    }

    private void setColorFilter(View v, Integer filter) {
        if (filter == null) v.getBackground().clearColorFilter();
        else {
            // To lighten instead of darken, try this:
            // LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
            LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
            v.getBackground().setColorFilter(darken);
        }
        // required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
        v.getBackground().invalidateSelf();
    }
});

ho estratto questo come una classe separata per l'applicazione su più pulsanti -. Indicato come classe interna anonima solo per avere l'idea

Se si stanno facendo tasti di colore con XML è possibile rendere il codice un po 'più pulito specificando lo stato mirato e pressato in un file separato e riutilizzarli. Il mio tasto verde si presenta così:

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

    <item android:state_focused="true" android:drawable="@drawable/button_focused"/>
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>

    <item>
        <shape>
            <gradient android:startColor="#ff00ff00" android:endColor="#bb00ff00" android:angle="270" />
            <stroke android:width="1dp" android:color="#bb00ff00" />
            <corners android:radius="3dp" />
            <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
        </shape>
    </item>

</selector>

La soluzione più breve che sta lavorando con qualsiasi versione di Android:

<Button
     app:backgroundTint="@color/my_color"

Note / Requisiti :

  • Utilizza lo spazio dei nomi app: e non il namespace android:!
  • appcompat versione> 24.2.0

    dipendenze {     compilare 'com.android.support:appcompat-v7:25.3.1' }

Spiegazione : entrare image description qui

Sto usando questo approccio

style.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:colorPrimaryDark">#413152</item>
    <item name="android:colorPrimary">#534364</item>
    <item name="android:colorAccent">#534364</item>
    <item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>

<style name="MyButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">#534364</item>
    <item name="android:textColor">#ffffff</item>
</style>

Come si può vedere da sopra, sto usando uno stile personalizzato per il mio tasto. Il colore del pulsante corrispondente al colore accento. Trovo che questo sia un approccio molto meglio di impostazione android:background come io non voglio perdere l'effetto complessivo di Google fornisce.

C'è un modo molto più semplice ora: android-holo-colors.com

Vi permette di cambiare i colori di tutti Holo drawable (pulsanti, filatori, ...) in modo semplice. Si seleziona il colore e quindi scaricare un file zip contenente drawable per tutte le risoluzioni.

Si usa in questo modo:

buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);

In <Button> uso android:background="#33b5e5". o meglio android:background="@color/navig_button"

Il DroidUX libreria di componenti ha un widget di ColorButton il cui colore può essere cambiato facilmente, sia attraverso la definizione di XML e di programmazione in fase di esecuzione, così si può anche permettere all'utente di impostare il colore del pulsante / tema, se la vostra applicazione lo permette.

È possibile utilizzare anche questo strumento online per personalizzare il pulsante http://angrytools.com/android/button/ e l'uso android:background="@drawable/custom_btn" per definire il pulsante personalizzato nel layout.

È possibile impostare il tema del pulsante a questo

<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
 <item name="colorButtonNormal">@color/HEXColor</item>
 <item name="android:textColor">@color/HEXColor</item>
</style>

Un modo semplice è quello di definire solo una classe pulsante personalizzato che accetta tutte le proprietà che desiderate come raggio, pendenza, colore pressato, ecc colore normale e poi basta usare che nei vostri layout XML invece di impostare lo sfondo utilizzando XML. Un campione è qui

Questo è estremamente utile se si hanno un sacco di pulsanti con stesse proprietà come raggio, colore, ecc selezionato È possibile personalizzare il tasto ereditato per gestire queste proprietà aggiuntive.

Risultato (No selettore Sfondo è stato utilizzato).

Normal

Immagine Normale

Pulsante Premuto

entrare descrizione dell'immagine qui

Il mio modo di fare un pulsante in stile diverso che funziona abbastanza bene è quello di creare una sottoclasse dell'oggetto Button e applicare un filtro di colore. Questo anche maniglie abilitati e disabilitati stati applicando un alfa al pulsante.

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Button;

public class DimmableButton extends Button {

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

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

    public DimmableButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setBackgroundDrawable(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackgroundDrawable(layer);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void setBackground(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackground(layer);
    }

    /**
     * The stateful LayerDrawable used by this button.
     */
    protected class DimmableButtonBackgroundDrawable extends LayerDrawable {

        // The color filter to apply when the button is pressed
        protected ColorFilter _pressedFilter = new LightingColorFilter(Color.LTGRAY, 1);
        // Alpha value when the button is disabled
        protected int _disabledAlpha = 100;
        // Alpha value when the button is enabled
        protected int _fullAlpha = 255;

        public DimmableButtonBackgroundDrawable(Drawable d) {
            super(new Drawable[] { d });
        }

        @Override
        protected boolean onStateChange(int[] states) {
            boolean enabled = false;
            boolean pressed = false;

            for (int state : states) {
                if (state == android.R.attr.state_enabled)
                    enabled = true;
                else if (state == android.R.attr.state_pressed)
                    pressed = true;
            }

            mutate();
            if (enabled && pressed) {
                setColorFilter(_pressedFilter);
            } else if (!enabled) {
                setColorFilter(null);
                setAlpha(_disabledAlpha);
            } else {
                setColorFilter(null);
                setAlpha(_fullAlpha);
            }

            invalidateSelf();

            return super.onStateChange(states);
        }

        @Override
        public boolean isStateful() {
            return true;
        }
    }

}

Valori \ styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="RedAccentButton" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">#ff0000</item>
</style>

quindi:

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text"
    android:theme="@style/RedAccentButton" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text"
    android:theme="@style/RedAccentButton" />

risultato

Per linee guida di progettazione dei materiali, è necessario utilizzare lo stile come     sotto codice

<style name="MyButton" parent="Theme.AppCompat.Light>
    <item name="colorControlHighlight">#F36F21</item>
    <item name="colorControlHighlight">#FF8D00</item>
</style>

e nel layout Aggiungi questa proprietà al pulsante

    android:theme="@style/MyButton"

La sua semplice .. aggiungere questa dipendenza nel progetto e creare un pulsante con 1. Qualsiasi forma 2. Qualsiasi colore 3. Ogni confine 4. Con effetti materiali

https://github.com/manojbhadane/QButton

<com.manojbhadane.QButton
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="OK"
       app:qb_backgroundColor="@color/green"
       app:qb_radius="100"
       app:qb_strokeColor="@color/darkGreen"
       app:qb_strokeWidth="5" />
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top