Pulsanti da colorare in Android con Material Design e AppCompat


256

Prima che AppCompatuscisse l' aggiornamento oggi sono stato in grado di cambiare il colore dei pulsanti in Android L ma non nelle versioni precedenti. Dopo aver incluso il nuovo aggiornamento AppCompat, non riesco a cambiare il colore per nessuna delle versioni, quando provo il pulsante scompare. Qualcuno sa come cambiare il colore del pulsante?

Le seguenti immagini mostrano ciò che voglio ottenere:

immagine che mostra il risultato desiderato

Il pulsante bianco è predefinito, quello rosso è quello che voglio.

Questo è ciò che stavo facendo in precedenza per cambiare il colore dei pulsanti in styles.xml:

<item name="android:colorButtonNormal">insert color here</item>

e per farlo in modo dinamico:

button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);

Inoltre ho cambiato il tema genitore da @android:style/Theme.Material.Light.DarkActionBaraTheme.AppCompat.Light.DarkActionBar


Ho provato lo stesso ma nulla ha cambiato il colore del pulsante. Ho anche rimosso Android: dall'attributo perché proviene dalla libreria di supporto e non fa parte dello spazio dei nomi Android
Informatic0re

Se stai usando Android: colorButtonNormal con Android 5.0 funziona - ma sembra non essere compatibile con le versioni precedenti
Informatic0re

Sì, è esattamente quello che stavo vivendo
mail929,

Ho anche capito che il colore dell'accento non cambia il colore di CheckBox, ma lo fa nelle versioni precedenti
Informatic0re

più uno per quel metodo dinamico. :)
theapache64

Risposte:


222

Riparato ufficialmente nella Support Library rev.22 (venerdì 13 marzo 2015). Vedi il problema relativo al codice Google:

https://issuetracker.google.com/issues/37008632

Esempio di utilizzo

theme.xml:

<item name="colorButtonNormal">@color/button_color</item>

v21 / theme.xml

<item name="android:colorButtonNormal">@color/button_color</item>

17
C'è qualche esempio su come usarlo? Come posso impostare i colori su un solo pulsante?
Intrighi

3
@WindRider Ho un problema però, voglio usarlo per creare pulsanti con colori diversi. Creo stili Button.Red, Button.Green, tutti con genitore uguale a Button base style. Ho impostato l'elemento colorButtonNormal sul colore richiesto, impostandolo come tema pulsante. Sfortunatamente colora solo i pulsanti per 21. Sotto non sovrascrive colorButtonNormal definito nel tema.
dominik4142

71
Con AppCompat 22.1.1 funziona per me su 2.3.7, 4.4.4 e 5.1 anche per un solo pulsante: impostazione del pulsante android:theme="@style/ColoredButton"e in styles.xml <style name="ColoredButton" parent="Widget.AppCompat.Button"> <item name="colorButtonNormal">@color/button_yellow</item> </style>
hunyadym

2
@hunyadym, l'aggiunta di un tema al pulsante si interrompe su Fai clic per qualche motivo. Lo classificherei come una soluzione alternativa fino a quando la libreria Design non fornirà un modo migliore.
accolto il

3
@gladed: nel tuo caso sembra che il problema sia questo bug: code.google.com/p/android/issues/detail?id=62795#c1
hunyadym

148

Modifica (22.06.2016):

La libreria di Appcompat ha iniziato a supportare i pulsanti dei materiali dopo aver pubblicato la risposta originale. In questo post puoi vedere l'implementazione più semplice dei pulsanti in rilievo e piatti.

Risposta originale:

Dal momento che AppCompat non supporta ancora il pulsante, puoi usare xml come sfondo. Per farlo ho dato un'occhiata al codice sorgente di Android e ho trovato i file correlati per i pulsanti del materiale di styling.

1 - Guarda l'implementazione originale del pulsante materiale dalla fonte.

Dai un'occhiata a btn_default_material.xml sul codice sorgente Android .

È possibile copiare il file nella cartella drawable-v21 dei progetti. Ma non toccare il colore attr qui. Il file che devi modificare è il secondo file.

Drawable-V21 / custom_btn.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
    <item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

2 - Ottieni la forma del pulsante del materiale originale

Quando ti rendi conto c'è una forma usata all'interno di questo disegno che puoi trovare in questo file del codice sorgente .

<inset xmlns:android="http://schemas.android.com/apk/res/android"
   android:insetLeft="@dimen/button_inset_horizontal_material"
   android:insetTop="@dimen/button_inset_vertical_material"
   android:insetRight="@dimen/button_inset_horizontal_material"
   android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
    <corners android:radius="@dimen/control_corner_material" />
    <solid android:color="?attr/colorButtonNormal" />
    <padding android:left="@dimen/button_padding_horizontal_material"
             android:top="@dimen/button_padding_vertical_material"
             android:right="@dimen/button_padding_horizontal_material"
             android:bottom="@dimen/button_padding_vertical_material" />
</shape>

3 - Ottenere le dimensioni del pulsante materiale

E in questo file ci sono alcune dimensioni utilizzate dal file che puoi trovare qui . È possibile copiare l'intero file e inserirlo nella cartella dei valori . Questo è importante per applicare la stessa dimensione (utilizzata nei pulsanti dei materiali) a tutti i pulsanti

4 - Crea un altro file disegnabile per le vecchie versioni

Per le versioni precedenti dovresti avere un altro disegno con lo stesso nome. Sto inserendo direttamente gli articoli in linea anziché fare riferimento. Potresti voler fare riferimento a loro. Ma ancora una volta, la cosa più importante sono le dimensioni originali del pulsante materiale.

drawable / custom_btn.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- pressed state -->
    <item android:state_pressed="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/PRESSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- focused state -->
    <item android:state_focused="true">
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/FOCUSED_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
    
    <!-- normal state -->
    <item>
        <inset xmlns:android="http://schemas.android.com/apk/res/android"
            android:insetLeft="@dimen/button_inset_horizontal_material"
            android:insetTop="@dimen/button_inset_vertical_material"
            android:insetRight="@dimen/button_inset_horizontal_material"
            android:insetBottom="@dimen/button_inset_vertical_material">
            <shape android:shape="rectangle">
                <corners android:radius="@dimen/control_corner_material" />
                <solid android:color="@color/NORMAL_STATE_COLOR" />
                <padding android:left="@dimen/button_padding_horizontal_material"
                    android:top="@dimen/button_padding_vertical_material"
                    android:right="@dimen/button_padding_horizontal_material"
                    android:bottom="@dimen/button_padding_vertical_material" />
            </shape>
        </inset>
    </item>
</selector>

Risultato

Il tuo pulsante avrà un effetto a catena sui dispositivi Lollipop. Le vecchie versioni avranno esattamente lo stesso pulsante tranne l'effetto a catena. Ma dal momento che fornisci disegnabili per diversi stati, risponderanno anche agli eventi di tocco (come alla vecchia maniera).


4
Si, esattamente. Se usi lo stesso sfondo per tutti i pulsanti e se non vuoi aggiungerlo più e più volte, definisci uno stile di pulsante nel tuo styles.xml <style name = "ButtonStyle" parent = "android: Widget.Button"> < item name = "android: background"> ​​@ drawable / custom_btn </item> </style> e aggiungi lo stile del pulsante nel tuo tema <item name = "android: buttonStyle"> @ style / ButtonStyle </item>
eluleci

1
come posso aggiungere l'elevazione a questo pulsante su pre-21? a quanto ho capito dovrei aggiungere una nuova forma con il pulsante ombra in basso, ma dove dovrei metterlo esattamente?
Xakz,

7
Molto fastidioso che questo non sia supportato fuori dalla scatola
Sam

39
Sono totalmente d'accordo con te. Il pulsante è il widget maggiormente utilizzato, ma non è incluso nella libreria di supporto per il materiale. Mi chiedo cosa stessero pensando.
eluleci,

1
Inoltre, seguendo la tua guida sembra che lo sfondo non si mostri affatto ...
JMRboosties

111

Questo è stato migliorato nella v23.0.0 della libreria AppCompat con l'aggiunta di più temi tra cui

Widget.AppCompat.Button.Colored

Prima di tutto includi la dipendenza appCompat se non l'hai già fatto

compile('com.android.support:appcompat-v7:23.0.0') {
    exclude group: 'com.google.android', module: 'support-v4'
}

ora che devi usare la v23 dell'app compat, dovrai anche scegliere come target SDK-v23!

    compileSdkVersion = 23
    targetSdkVersion = 23

Nel tuo values/theme

<item name="android:buttonStyle">@style/BrandButtonStyle</item>

Nel tuo values/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

Nel tuo values-v21/style

<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">@color/yourButtonColor</item>
    <item name="android:textColor">@color/White</item>
</style>

Poiché il tema del pulsante è basato su Widget.AppCompat.Button.ColoredIl colore del testo sul pulsante è di default bianco!

ma sembra che ci sia un problema quando si disabilita il pulsante, il pulsante cambierà colore in grigio chiaro, ma il colore del testo rimarrà bianco!

una soluzione alternativa è quella di impostare in modo specifico il colore del testo sul pulsante su bianco! come ho fatto nello stile mostrato sopra.

ora puoi semplicemente definire il tuo pulsante e lasciare che AppCompat faccia il resto :)

<Button
        android:layout_width="200dp"
        android:layout_height="48dp" />

Stato per disabili Stato disabilitato

Stato abilitato Stato abilitato

Modificare:

Aggiungere <Button android:theme="@style/BrandButtonStyle"/>


19
Questo è il modo migliore per farlo, ora! Puoi anche usare lo stile sui singoli pulsanti con <Button android:theme="@style/BrandButtonStyle"/>. Deve essere l' themeattributo e non l' styleattributo.
Mohlendo,

7
@Muhammad Alfaifi Hai un progetto di esempio o un'idea per questo? Ho creato un progetto pulito e non funziona: github.com/Bresiu/ThemeTest . Nei colori dei pulsanti Lolipop con accento e su API v16, il pulsante rimane grigio: i.imgur.com/EVwkpk2.png
Bresiu,

4
Questo ha funzionato solo per me quando si specifica l'attributo android: theme. Non sono riuscito a far funzionare lo stile dell'attributo con il tag button.
Ray Hunter,

8
Usando la libreria v23.1, questo non funzionava correttamente, mostrava sempre il colore dell'accento come bg, non quello definito, quando cercava di impostarlo sull'intero tema
Patrick Favre,

3
Stesso problema qui, su v23.1 il pulsante disabilitato ha lo stesso colore del pulsante abilitato. molto frustrante. qualcuno lo capisce?
Ahmed,

63

Nella libreria di supporto Android 22.1.0, Google ha reso Buttonnota la tinta. Quindi, un altro modo per personalizzare il colore di sfondo del pulsante è usare l' backgroundTintattributo.

Per esempio,

<Button
       android:id="@+id/add_remove_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:backgroundTint="@color/bg_remove_btn_default"
       android:textColor="@android:color/white"
       tools:text="Remove" />

1
Finalmente! Post di blog sulla versione 22.1: android-developers.blogspot.no/2015/04/…
GuillermoMP

5
La documentazione dice: "Questo verrà usato automaticamente quando usi Button nei tuoi layout. Dovresti usare questa classe solo quando scrivi viste personalizzate." developer.android.com/reference/android/support/v7/widget/… significa che non dobbiamo modificare manualmente tutti i nostri layout e il codice java?
Stephane,

@Stephane no, dovremmo cambiare layout. chris.banes.me/2015/04/22/support-libraries-v22-1-0
Anton Holovin

ECCEZIONALE! Ora, c'è un AppCompatToggleButton che ti consente di cambiare lo sfondo di ToggleButtons? Forse posso plagiare il codice ...
svenendo il

19
Sfortunatamente questo funziona solo su API 21+. L'attributo android: backgroundTint non funziona su pre-Lollipop anche con la libreria AppCompat. Solo colorButtonNormal dal tema funziona su pre-Lollipop.
Timur_C,

42

Per supportare i pulsanti colorati usa l'ultima libreria AppCompat (> 23.2.1 ) con:

gonfiare - XML

Widget AppCompat:

android.support.v7.widget.AppCompatButton

Stile AppCompat:

style="@style/Widget.AppCompat.Button.Colored"

NB! Per impostare un colore personalizzato in xml: utilizzare l'attr: appanzichéandroid

(usa alt+entero dichiara xmlns:app="http://schemas.android.com/apk/res-auto"di usare app)

app : backgroundTint = "@ color / your_custom_color"

Esempio:

<android.support.v7.widget.AppCompatButton
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/your_custom_color"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"     
     android:text="Colored Button"/>

o impostarlo a livello di codice - JAVA

 ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));

Il tuo codice Java ha funzionato per me. E la risposta di Muhammad Alfaifi ha contribuito a impostare il colore del testo del pulsante.
Micro

c'è un modo semplice per impostare programmaticamente la tinta (non lo sfondo)?
caveau

Meraviglioso! Funziona anche su 4.4.4! E anche lo stato del selettore viene mantenuto abbastanza bene!
sud007,

Secondo i documenti : viene utilizzato automaticamente quando si impostano i pulsanti nei layout. Devi solo specificare AppCompatButton durante la creazione di viste personalizzate.
gMale

È interessante notare che le modifiche XML hanno funzionato perfettamente in un frammento ma non in un layout di attività. I pulsanti Attività utilizzavano solo colorAccent. La versione programmatica ha funzionato però.
Leon,

25

Con l'ultima libreria di supporto da cui potresti semplicemente ereditare la tua attività AppCompatActivity, così si gonfia il tuo Buttonas AppCompatButtone ti darà l'opportunità di dare uno stile al colore di ogni singolo pulsante sul layout con l'utilizzo di android:theme="@style/SomeButtonStyle", dove si SomeButtonStyletrova:

<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
    <item name="colorButtonNormal">@color/example_color</item>
</style>

Ha funzionato per me in 2.3.7, 4.4.1, 5.0.2


Grazie!!! Ho appena cambiato il valore genitore per "Widget.AppCompat.EditText" in quanto ho bisogno di aggiornare lo stile EditText.
Juan Saravia,

3
Grazie, ha lavorato anche per me. Assicurati di usare android:themee non style. Puoi anche aggiungere colorControlHighlighte colorControlActivated.
Rachel,

non funziona, API 22, AppCompatActivity, tema Material.Light
Andrey Uglev

1
@AndreyUglev tenta Theme.AppCompat.Lightinvece di utilizzare .
Artem,

Ciao, cambia il colore desiderato MA rimuove le ombre.
Amio.io

16

se vuoi sotto stile

inserisci qui la descrizione dell'immagine

aggiungi questo stile al tuo pulsante

style="@style/Widget.AppCompat.Button.Borderless.Colored"

se vuoi questo stile

inserisci qui la descrizione dell'immagine

aggiungi sotto il codice

style="@style/Widget.AppCompat.Button.Colored"

1
compile 'com.android.support:appcompat-v7:23.1.0'Devi aggiungere.
Pratik Butani,

1
ma la domanda è come avere pulsanti materiali con colori diversi, in modo che non tutti abbiano il colore primario del tema.
Apostrofix,

15

La risposta è in TEMA non in stile

Il problema è che il colore del pulsante si attacca al colorButtonNormal del tema. Ho provato a cambiare lo stile in molti modi diversi senza fortuna. Quindi ho cambiato il tema del pulsante .

Crea un tema con colorButtonNormal e colorPrimary:

<style name="ThemeAwesomeButtonColor" parent="AppTheme">
    <item name="colorPrimary">@color/awesomePrimaryColor</item>
    <item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>

Usa questo tema nel pulsante

<Button
        android:id="@+id/btn_awesome"
        style="@style/AppTheme.Button"
        android:theme="@style/ThemeAwesomeButtonColor"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_awesome"/>

"AppTheme.Button" può essere qualsiasi cosa si estende Stile del pulsante come qui Uso il colore primario per il colore del testo:

<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
    ...
    <item name="android:textColor">?attr/colorPrimary</item>
    ...
</style>

E ottieni il pulsante in qualsiasi colore che desideri compatibile con il design dei materiali.


quali sono gli altri attributi che posso aggiungere agli stili.
Sagar Nayak,

4

Ho appena creato una libreria Android, che ti consente di modificare facilmente il colore del pulsante e il colore dell'ondulazione

https://github.com/xgc1986/RippleButton

<com.xgc1986.ripplebutton.widget.RippleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    android:text="Android button modified in layout"
    android:textColor="@android:color/white"
    app:buttonColor="@android:color/black"
    app:rippleColor="@android:color/white"/>

Non è necessario creare uno stile per ogni pulsante desiderato con un colore diverso, che consente di personalizzare i colori in modo casuale


4

questo lavoro per me con appcompat-v7: 22.2.0 in Android + 4.0

nel tuo styles.xml

<style name="Button.Tinted" parent="Widget.AppCompat.Button">
    <item name="colorButtonNormal">YOUR_TINT_COLOR</item>
    <item name="colorControlHighlight">@color/colorAccent</item>
    <item name="android:textColor">@android:color/white</item>
</style>

nel tuo file di layout

<Button
    android:id="@+id/but_next"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/but_continue"
    android:theme="@style/Button.Tinted" />

Ciao, cambia il colore desiderato MA rimuove le ombre.
Amio.io

Ciao di nuovo, posso vedere. È un comportamento corretto ora.
Amio.io,

Come puoi farlo in Java?
Micro

@MicroR controlla la risposta sopra.
ingyesid,

4

Disposizione:

<android.support.v7.widget.AppCompatButton
  style="@style/MyButton"
  ...
  />

styles.xml:

<style name="MyButton" parent="Widget.AppCompat.Button.Colored">
  <item name="backgroundTint">@color/button_background_selector</item>
  <item name="android:textColor">@color/button_text_selector</item>
</style>

colore / button_background_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#555555"/>
    <item android:color="#00ff00"/>
</selector>

colore / button_text_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="#888888"/>
    <item android:color="#ffffff"/>
</selector>

3

Per quelli che usano un ImageButton qui è come lo fai:

In style.xml:

<style name="BlueImageButton" parent="Base.Widget.AppCompat.ImageButton">
    <item name="colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

in v21 / style.xml:

<style name="BlueImageButton" parent="Widget.AppCompat.ImageButton">
    <item name="android:colorButtonNormal">@color/primary</item>
    <item name="android:tint">@color/white</item>
</style>

Quindi nel tuo file di layout:

<android.support.v7.widget.AppCompatImageButton
    android:id="@+id/my_button"
    android:theme="@style/BlueImageButton"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:layout_gravity="center_vertical"
    android:src="@drawable/ic_check_black_24dp"
    />

Questo ha aiutato .... Immagino sia importante notare come applicare lo stile del pulsante come tema anziché come stile nel widget Pulsante. Lo stavo applicando sotto style = "@ style / BlueImageButton" e non ha funzionato
velval

3

Se usi la soluzione di stile con colorButtonNormal , non dimenticare di ereditare da Widget.AppCompat.Button.Colored modo che l'effetto a ;)

Piace

<style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
      <item name="colorButtonNormal">@android:color/white</item>
</style>

2

Un'altra soluzione semplice che utilizza AppCompatButton

<android.support.v7.widget.AppCompatButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     style="@style/Widget.AppCompat.Button.Colored"
     app:backgroundTint="@color/red"
     android:text="UNINSTALL" />

2

Uso:

android:backgroundTint="@color/customColor"

O anche :

android:background="@color/customColor"

e questo darà un colore personalizzato al pulsante.


1

Se vuoi solo il pulsante "Flat" del materiale, puoi personalizzare il loro sfondo usando l' attributo selectableItemBackground come spiegato qui .


Se non vuoi cambiare nessuno dei colori "tinta" o colori selezionati, questa è sicuramente una soluzione semplice per ottenere un feedback con i pulsanti colorati. Grazie!
theblang,

1

Per cambiare il colore di un singolo pulsante

ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));

1

Per me, il problema era che in Android 5.0 android:colorButtonNormalnon aveva alcun effetto, e in realtà, nessun elemento dal tema (come android:colorAccent), ma in Android 4.4.3, per esempio, lo faceva. Il progetto è stato configurato con compileSdkVersione targetSdkVersionsu 22, quindi ho apportato tutte le modifiche come suggerito da @Muhammad Alfaifi, ma alla fine ho notato che il problema era buildToolsVersion , che non è stato aggiornato. Una volta cambiato in 23.0.1 , tutto inizia a funzionare quasi normalmente. Ora, il risultato android:colorButtonNormalnon ha ancora alcun effetto, ma almeno il pulsante reagisce android:colorAccent, il che per me è accettabile.

Spero che questo suggerimento possa aiutare qualcuno. Nota: ho applicato lo stile direttamente al pulsante, poiché anche il pulsante android:theme=[...]non ha avuto effetto.


È quasi trovato il modo corretto al 100% come utilizzare le nuove @ stile / Widget.AppCompat.Button.Colored;) - vedere questa risposta stackoverflow.com/a/35811157/19733911
sosite

1

Un modo per farlo ti consente di puntare a uno stile e NON a tema TUTTI i pulsanti della tua app allo stesso modo.
In themes.xml aggiungi un tema

    <style name="Theme.MyApp.Button.Primary.Blue" parent="Widget.AppCompat.Button">
        <item name="colorButtonNormal">@color/someColor</item>
        <item name="android:textColorPrimary">@android:color/white</item>
    </style>

Ora in styles.xml aggiungi

    <style name="MyApp.Button.Primary.Blue" parent="">
        <item name="android:theme">@style/Theme.MyApp.Button.Primary.Blue</item>
    </style>

Ora nel tuo layout punta semplicemente allo STILE nel tuo pulsante

    <Button
        ...
        style="@style/MyApp.Button.Primary.Blue"
        ...  />

1

AGGIORNARE

Utilizzare la libreria di supporto alla progettazione (23.2.0) e i widget appcompat come di seguito

Nella libreria di supporto Android 22.1 :

Questo viene fatto automaticamente quando si gonfiano i layout - sostituendo Button con AppCompatButton, TextView con AppCompatTextView, ecc. Per garantire che ciascuno possa supportare la colorazione. In questa versione, i widget con colorazione sono ora disponibili pubblicamente, consentendo di mantenere il supporto per la colorazione anche se è necessario sottoclassare uno dei widget supportati.

L'elenco completo dei widget sensibili al colore:

AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView

Design del materiale per dispositivi pre-lecca-lecca :

AppCompat (aka ActionBarCompat) è nato come backport dell'API ActionBar per Android 4.0 per dispositivi in ​​esecuzione su Gingerbread, fornendo un livello API comune oltre all'implementazione backportata e all'implementazione del framework. AppCompat v21 offre un'API e un set di funzionalità aggiornati con Android 5.0



1

Se si desidera utilizzare lo stile AppCompat come Widget.AppCompat.Button , Base.Widget.AppCompat.Button.Colored , ecc., È necessario utilizzare questi stili con viste compatibili dalla libreria di supporto.

Il codice seguente non funziona per i dispositivi pre-lolipop:

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

È necessario utilizzare AppCompatButton per abilitare gli stili AppCompat:

<android.support.v7.widget.AppCompatButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:theme="@style/Widget.AppCompat.Button" />

2
I widget compatibili con l'app non vengono utilizzati automaticamente quando si gonfiano i layout XML? Credo che ImageViewvenga sostituito AppCompatImageViewe dovrebbe essere lo stesso con tutti i widget, che hanno la AppCompatversione corrispondente .
Demone

No, se non scegli come target l'ultima versione di destinazione, devi definire android.support.v7.widget.AppCompatImageViewesplicitamente.
Farukcankaya,

Cosa intendi con last target version@power?
Demone

1

Io lo uso Effetto increspatura e pulsante ombra del pulsante funzionante

style.xml

<style name="Button.Red" parent="Widget.AppCompat.Button.Colored">
    <item name="android:textColor">@color/material_white</item>
    <item name="android:backgroundTint">@color/red</item>
</style>

Pulsante sul layout:

<Button
        style="@style/Button.Red"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/close"/>

0

In realtà non volevo cambiare i miei stili di pulsanti personalizzati, ma sfortunatamente non funzionavano più.

La mia app ha una versione minSdk di 9 e tutto ha funzionato prima.

Non so perché ma da quando ho rimosso Android: prima di ButtonStyle sembra funzionare di nuovo

ora = funzionante:

<item name="buttonStyle">@style/ButtonmyTime</item>

prima = solo pulsanti di materiale grigio:

<item name="android:buttonStyle">@style/ButtonmyTime</item>

Non ho una cartella speciale per la nuova versione di Android poiché i miei pulsanti sono abbastanza piatti e dovrebbero apparire uguali in tutte le versioni di Android.

Forse qualcuno può dirmi perché ho dovuto rimuovere "android:" ImageButton funziona ancora con "android:"

<item name="android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>

0

Dopo 2 giorni in cerca di risposte, il tema del pulsante non ha funzionato per me in API <21.

La mia unica soluzione è quella di sostituire la colorazione di AppCompatButton non solo con il tema dell'app di base "colorButtonNormal", ma anche con lo sfondo della vista.

public class AppCompatColorButton extends AppCompatButton {

    public AppCompatColorButton(Context context) {
        this(context, null);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs) {
        this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle);
    }

    public AppCompatColorButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        if (TintManager.SHOULD_BE_USED) {
            setSupportBackgroundTintList(createButtonColorStateList(getContext(), attrs, defStyleAttr));
        }
    }

    static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
    static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
    static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
    static final int[] EMPTY_STATE_SET = new int[0];

    private ColorStateList createButtonColorStateList(Context context, AttributeSet attrs, int defStyleAttr) {
        final int[][] states = new int[4][];
        final int[] colors = new int[4];
        int i = 0;

        final int themeColorButtonNormal = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        /*TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/
        TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.View, defStyleAttr, 0);
        final int colorButtonNormal = a.getColor(android.support.v7.appcompat.R.styleable.View_backgroundTint, themeColorButtonNormal);
        a.recycle();
        final int colorControlHighlight = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorControlHighlight);

        // Disabled state
        states[i] = DISABLED_STATE_SET;
        colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
        i++;

        states[i] = PRESSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        states[i] = FOCUSED_STATE_SET;
        colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
        i++;

        // Default enabled state
        states[i] = EMPTY_STATE_SET;
        colors[i] = colorButtonNormal;
        i++;

        return new ColorStateList(states, colors);
    }
}

È quindi possibile definire il colore del pulsante in questo modo:

<com.example.views.AppCompatColorButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:backgroundTint="#ffff0000"
            app:backgroundTint="#ffff0000"
            android:text="Button"
            android:textColor="@android:color/white" />

0

Questa risposta SO mi ha aiutato a ottenere una risposta https://stackoverflow.com/a/30277424/3075340

Uso questo metodo di utilità per impostare la tonalità di sfondo di un pulsante. Funziona con dispositivi pre-lecca-lecca:

// Set button background tint programmatically so it is compatible with pre-lollipop devices.
public static void setButtonBackgroundTintAppCompat(Button button, ColorStateList colorStateList){
    Drawable d = button.getBackground();
    if (button instanceof AppCompatButton) {
        // appcompat button replaces tint of its drawable background
        ((AppCompatButton)button).setSupportBackgroundTintList(colorStateList);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Lollipop button replaces tint of its drawable background
        // however it is not equal to d.setTintList(c)
        button.setBackgroundTintList(colorStateList);
    } else {
        // this should only happen if
        // * manually creating a Button instead of AppCompatButton
        // * LayoutInflater did not translate a Button to AppCompatButton
        d = DrawableCompat.wrap(d);
        DrawableCompat.setTintList(d, colorStateList);
        button.setBackgroundDrawable(d);
    }

}

Come usare nel codice:

Utility.setButtonBackgroundTintAppCompat(myButton,
ContextCompat.getColorStateList(mContext, R.color.your_custom_color));

In questo modo, non è necessario specificare un ColorStateList se si desidera solo cambiare la tinta di sfondo e nient'altro, ma mantenere gli effetti dei pulsanti graziosi e cosa no.


0

Ho impostato android:textColoral @nullmio tasto tema e mi aiuta.

styles.xml

<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored">
    <item name="android:textColor">@null</item>
</style>

some_layout.xml

<Button
    style="@style/Button.Base.Borderless"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hint" />

Ora il colore del testo del pulsante è colorAccentdefinito inAppTheme

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/colorAccent</item>
    <item name="borderlessButtonStyle">@style/Button.Base.Borderless</item>
    <item name="alertDialogTheme">@style/AlertDialog</item>
</style>

0

se usi kotlin, puoi vedere Tutti gli attributi di MaterialButton sono supportati. Non utilizzare l'attributo android: background. MaterialButton gestisce il proprio disegno di sfondo e l'impostazione di un nuovo sfondo significa che il colore del pulsante Materiale disabilitato non può più garantire che i nuovi attributi che introduce funzionino correttamente. Se lo sfondo predefinito viene modificato, il pulsante Materiale non può garantire un comportamento ben definito. A MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        buttonClick.setOnClickListener {
            (it as MaterialButton).apply {
                backgroundTintList = ColorStateList.valueOf(Color.YELLOW)
                backgroundTintMode = PorterDuff.Mode.SRC_ATOP
            }
        }
    }
}

A activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraintLayout"
    tools:context=".MainActivity">
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonNormal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Material Button Normal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonTint"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#D3212D"
        android:text="Material Button Background Red"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonNormal" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonTintMode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#D3212D"
        android:backgroundTintMode="multiply"
        android:text="Tint Red + Mode Multiply"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonTint" />
    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonClick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Click To Change Background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonTintMode" />
</androidx.constraintlayout.widget.ConstraintLayout>

risorsa: esempio di cambio colore del pulsante Materiale


0

se vuoi farlo tramite un codice di qualsiasi colore, usa questo:

DrawableCompat.setTintList(button.getBackground(), ColorStateList.valueOf(yourColor));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.