Colorir botões no Android com Material Design e AppCompat


256

Antes da AppCompatatualização ser lançada hoje, eu era capaz de alterar a cor dos botões no Android L, mas não nas versões mais antigas. Depois de incluir a nova atualização do AppCompat, não consigo alterar a cor das duas versões, quando tento o botão simplesmente desaparece. Alguém sabe como mudar a cor do botão?

As figuras a seguir mostram o que eu quero alcançar:

imagem mostrando o resultado desejado

O botão branco é o padrão, o vermelho é o que eu quero.

Isto é o que eu estava fazendo anteriormente para alterar a cor dos botões no styles.xml:

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

e para fazer isso dinamicamente:

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

Também mudei o tema pai de @android:style/Theme.Material.Light.DarkActionBarparaTheme.AppCompat.Light.DarkActionBar


Tentei o mesmo, mas nada mudou a cor do botão. Eu também removeu android: a partir do atributo becouse é a partir da lib apoio e não faz parte do namespace android
Informatic0re

Se você estiver usando android: colorButtonNormal com Android 5.0 funciona - mas não parece ser compatível com versões anteriores
Informatic0re

Sim, isso é exatamente o que eu estava experimentando
mail929

Eu também descobri que a cor acento não muda a cor CheckBox, mas ele faz em versões mais antigas
Informatic0re

mais um para esse método dinâmico. :)
theapache64

Respostas:


222

Oficialmente corrigido na Biblioteca de suporte rev.22 (13 de março de 2015). Veja o problema relevante do código do Google:

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

Exemplo de uso

theme.xml:

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

v21 / theme.xml

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

17
Existe algum exemplo de como usá-lo? Como definir cores em apenas um botão?
Intrications

3
@ WindRider No entanto, eu tenho um problema, quero usá-lo para criar botões com cores diferentes. Eu crio estilos Button.Red, Button.Green, todos com pai igual ao estilo base do botão. Defino o item colorButtonNormal como cor solicitada, defina-o como tema do botão. Infelizmente, apenas cores botões para 21. Abaixo, ele não substitui colorButtonNormal definido no tema.
dominik4142

71
Com AppCompat 22.1.1 ele trabalha para mim em 2.3.7, 4.4.4 e 5.1 demais para um botão só: a criação do botão android:theme="@style/ColoredButton", e em styles.xml <style name="ColoredButton" parent="Widget.AppCompat.Button"> <item name="colorButtonNormal">@color/button_yellow</item> </style>
hunyadym

2
@hunyadym, adicionar um tema às quebras de botões no Click por algum motivo. Eu classificaria isso como uma solução alternativa até que a biblioteca Design forneça uma maneira melhor.
gladed

3
@gladed: Parece que no seu caso, o problema é esse bug: code.google.com/p/android/issues/detail?id=62795#c1
hunyadym

148

Editar (22.06.2016):

A biblioteca Appcompat começou a oferecer suporte aos botões de material depois que eu publiquei a resposta original. Nesta postagem, você pode ver a implementação mais fácil de botões elevados e planos.

Resposta original:

Como o AppCompat não suporta o botão, você pode usar o xml como plano de fundo. Para fazer isso, dei uma olhada no código-fonte do Android e encontrei os arquivos relacionados para criar botões de material.

1 - Veja a implementação original do botão de material da fonte.

Dê uma olhada no btn_default_material.xml no código fonte do Android .

Você pode copiar o arquivo na pasta drawable-v21 de projetos. Mas não toque na cor aqui. O arquivo que você precisa alterar é o segundo arquivo.

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 - Obtenha a forma do botão do material original

Como você percebe, há uma forma usada dentro deste drawable que você pode encontrar neste arquivo do código-fonte .

<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 - Obter dimensões do botão de material

E neste arquivo, existem algumas dimensões usadas no arquivo que você pode encontrar aqui . Você pode copiar o arquivo inteiro e colocá-lo na sua pasta de valores . Isso é importante para aplicar o mesmo tamanho (usado nos botões de material) a todos os botões

4 - Crie outro arquivo drawable para versões antigas

Para versões mais antigas, você deve ter outro drawable com o mesmo nome. Estou colocando os itens diretamente em linha, em vez de fazer referência. Você pode querer referenciá-los. Mas, novamente, o mais importante são as dimensões originais do botão de material.

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>

Resultado

Seu botão terá efeito cascata nos dispositivos Lollipop. As versões antigas terão exatamente o mesmo botão, exceto o efeito cascata. Mas desde que você forneça desenhos para diferentes estados, eles também responderão a eventos de toque (como na maneira antiga).


4
Sim, exatamente. Se você usar o mesmo plano de fundo para todos os botões e se não quiser adicioná-lo repetidamente, defina um estilo de botão em seus styles.xml <style name = "ButtonStyle" parent = "android: Widget.Button"> < item name = "android: background"> ​​@ drawable / custom_btn </item> </style> e adicione estilo de botão no seu tema <item name = "android: buttonStyle"> @ style / ButtonStyle </item>
eluleci

1
como posso adicionar elevação a este botão na pré-21? pelo que entendi, devo adicionar nova forma com sombra abaixo do botão, mas onde exatamente devo colocá-lo?
Xkz

7
Muito chato que isso não seja suportado imediatamente
Sam

39
Eu concordo totalmente com você. O botão é o widget mais usado, mas não está incluído na biblioteca de suporte para materiais. Eu me pergunto o que eles estavam pensando.
eluleci

1
Além disso, seguindo o seu guia, parece que o plano de fundo não está aparecendo ...
JMRboosties

111

Isso foi aprimorado na v23.0.0 da biblioteca AppCompat com a adição de mais temas, incluindo

Widget.AppCompat.Button.Colored

Antes de tudo, inclua a dependência appCompat, se você ainda não tiver

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

agora que você precisa usar a v23 do aplicativo compatível, também precisará segmentar o SDK-v23!

    compileSdkVersion = 23
    targetSdkVersion = 23

Na tua values/theme

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

Na tua values/style

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

Na tua 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>

Como o tema do seu botão é baseado em Widget.AppCompat.Button.ColoredA cor do texto no botão é branca por padrão!

mas parece que há um problema quando você desativa o botão, o botão muda de cor para cinza claro, mas a cor do texto permanece branca!

Uma solução alternativa para isso é definir especificamente a cor do texto no botão para branco! como eu fiz no estilo mostrado acima.

agora você pode simplesmente definir seu botão e deixar o AppCompat fazer o resto :)

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

Estado desativado Estado desativado

Estado ativado Estado ativado

Editar:

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


19
Essa é a melhor maneira de fazer isso agora! Você também pode usar o estilo em botões individuais com <Button android:theme="@style/BrandButtonStyle"/>. Tem que ser o themeatributo e não o styleatributo.
mohlendo

7
@ Muhammad Alfaifi Você tem um exemplo de projeto ou essência para isso? Eu criei um projeto limpo e ele não funciona: github.com/Bresiu/ThemeTest . Em cores dos botões Lolipop com cor de destaque e sobre v16 API, botão permanece cinza: i.imgur.com/EVwkpk2.png
Bresiu

4
Isso só funcionou para mim ao especificar o atributo android: theme. Não foi possível obter o estilo do atributo para mim com a tag button.
Raio do caçador

8
Usando v23.1 lib, isso não funcionou corretamente, ele sempre mostrou a cor de destaque como BG, não aquele definido, ao tentar configurá-lo para todo o tema
Patrick Favre

3
Mesmo problema aqui, na v23.1, o botão desativado é da mesma cor que o botão ativado. muito frustrante. alguém descobriu isso?
precisa saber é

63

Na Biblioteca de suporte do Android 22.1.0, o Google tomou Buttonconhecimento da tonalidade. Portanto, outra maneira de personalizar a cor de fundo do botão é usar o backgroundTintatributo

Por exemplo,

<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! Postagem no blog sobre a versão 22.1: android-developers.blogspot.no/2015/04/…
GuillermoMP

5
A documentação diz: "Isso será usado automaticamente quando você usar o botão em seus layouts. Você só precisará usar manualmente essa classe ao escrever visualizações personalizadas". developer.android.com/reference/android/support/v7/widget/… isso significa que não precisamos alterar manualmente todos os nossos layouts e códigos java?
Stephane

@ Stephanie não, devemos mudar os layouts. chris.banes.me/2015/04/22/support-libraries-v22-1-0
Anton Holovin

IMPRESSIONANTE! Agora, existe um AppCompatToggleButton que permite alterar o plano de fundo dos ToggleButtons? Talvez eu possa plagiar o código ...
swooby

19
Infelizmente, isso funciona apenas na API 21+. O atributo android: backgroundTint não funciona no pré-pirulito, mesmo com a biblioteca AppCompat. Somente colorButtonNormal do tema funciona no pré-pirulito.
Timur_C

42

Para suportar botões coloridos, use a biblioteca AppCompat mais recente (> 23.2.1 ) com:

inflar - XML

Widget AppCompat:

android.support.v7.widget.AppCompatButton

Estilo AppCompat:

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

NB! Para definir uma cor personalizada em xml: use o attr: em appvez deandroid

(use alt+enterou declare xmlns:app="http://schemas.android.com/apk/res-auto"usar app)

app : backgroundTint = "@ color / your_custom_color"

Exemplo:

<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"/>

ou defina-o programaticamente - JAVA

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

Seu código Java funcionou para mim. E a resposta de Muhammad Alfaifi ajudou a definir a cor do texto do botão.
Micro

existe uma maneira fácil de definir programaticamente o tom (não o plano de fundo)?
vault

Maravilhoso! Funciona no 4.4.4 também! E o estado do seletor também é mantido muito bem!
sud007

De acordo com os documentos : isso é usado automaticamente ao definir botões em seus layouts. Você só precisa especificar AppCompatButton ao criar visualizações personalizadas.
gMale

Curiosamente, as alterações XML funcionaram perfeitamente em um fragmento, mas não em um layout de Atividade. Os botões de atividade usavam apenas colorAccent. A versão programática funcionou embora.
26417 Leon

25

Com a Biblioteca de suporte mais recente, você pode herdar sua atividade AppCompatActivity, para que ela inflate seu Buttonas AppCompatButtone lhe dê a oportunidade de estilizar a cor de cada botão no layout com o uso de android:theme="@style/SomeButtonStyle", onde SomeButtonStyleé:

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

Trabalhou para mim em 2.3.7, 4.4.1, 5.0.2


Obrigado!!! Acabei de alterar o valor pai para "Widget.AppCompat.EditText", pois preciso atualizar o estilo EditText.
Juan Saravia

3
Obrigado, trabalhou para mim também. Certifique-se de usar android:themee não style. Você também pode adicionar colorControlHighlighte colorControlActivated.
Rachel

não funciona, API 22, AppCompatActivity, tema Material.Light
Andrey Uglev

1
@AndreyUglev tente usar em seu Theme.AppCompat.Lightlugar.
Artem

Oi, ele muda a cor desejada, mas remove as sombras.
Amio.io 1/08

16

se você quiser abaixo do estilo

insira a descrição da imagem aqui

adicione este estilo seu botão

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

se você quer esse estilo

insira a descrição da imagem aqui

adicione código abaixo

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

1
compile 'com.android.support:appcompat-v7:23.1.0'Você deve adicionar.
Pratik Butani 30/11/2015

1
mas a questão é como ter botões de materiais com cores diferentes, para que nem todos tenham a cor principal do tema.
Apostrofix

15

A resposta está no TEMA, não no estilo

O problema é que a cor do botão permanece no colorButtonNormal do tema. Eu tentei mudar o estilo de muitas maneiras diferentes, sem sorte. Então eu mudei o tema do botão .

Crie um tema com colorButtonNormal e colorPrimary:

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

Use este tema no botão

<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"/>

O "AppTheme.Button" pode ser qualquer coisa que se estenda ao estilo do botão, como aqui eu uso a cor primária para a cor do texto:

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

E você obtém o botão na cor que desejar, compatível com o design do material.


Quais são os outros atributos que posso adicionar em estilos.
Sagar Nayak 22/03

4

Acabei de criar uma biblioteca Android, que permite modificar facilmente a cor do botão e a cor da ondinha

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"/>

Você não precisa criar um estilo para cada botão que deseja com uma cor diferente, permitindo que você personalize as cores aleatoriamente


4

este trabalho para mim com appcompat-v7: 22.2.0 no android + 4.0

em seus 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>

no seu arquivo de 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" />

Oi, ele muda a cor desejada, mas remove as sombras.
Amio.io 1/08

Oi novamente, eu posso ver. É um comportamento adequado agora.
Amio.io 3/08

Como você pode fazer isso em Java?
Micro

@MicroR verifique a resposta acima.
ingyesid

4

Layout:

<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>

color / 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>

color / 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

Para quem usa um ImageButtonaqui é como você faz:

No style.xml:

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

na 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>

Em seguida, no seu arquivo de 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"
    />

Isso ajudou ... Acho que é importante observar para aplicar o estilo do botão como um tema, em vez de um estilo no widget Botão. Eu estava aplicando-o sob style = "@ estilo / BlueImageButton" e não funcionou
velval

3

Se você usar a solução de estilo com colorButtonNormal , não esqueça de herdar o Widget.AppCompat.Button.Colored para que o efeito cascata esteja funcionando;)

Gostar

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

2

Outra solução simples usando o 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

Usar:

android:backgroundTint="@color/customColor"

Ou até:

android:background="@color/customColor"

e isso dará uma cor personalizada ao botão.


1

Se você deseja apenas o botão de material "Simples", é possível personalizar o plano de fundo usando o atributo selecionávelItemBackground, conforme explicado aqui .


Se você não deseja alterar nenhuma das cores de "tonalidade" ou cores selecionadas, essa é definitivamente uma solução fácil para obter feedback com os botões coloridos. Obrigado!
theblang

1

Para alterar a cor de um único botão

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

1

Para mim, o problema era que no Android 5.0 android:colorButtonNormalnão havia efeito e, na verdade, nenhum item do tema (como android:colorAccent), mas no Android 4.4.3, por exemplo. O projeto foi configurado com compileSdkVersione targetSdkVersionpara 22, então eu fiz todas as alterações conforme sugerido pelo @Muhammad Alfaifi, mas no final, notei que o problema era o buildToolsVersion , que não foi atualizado. Depois que mudei para 23.0.1 , tudo começou a funcionar quase como o normal. Agora, o android:colorButtonNormalainda não tem efeito, mas pelo menos o botão reage android:colorAccent, o que para mim é aceitável.

Espero que essa dica possa ajudar alguém. Nota: apliquei o estilo diretamente no botão, pois os botões android:theme=[...]também não tiveram efeito.


Você quase encontrou a maneira 100% correta de como usar o novo @ style / Widget.AppCompat.Button.Colored;) - veja esta resposta stackoverflow.com/a/35811157/19733911
sosite

1

Uma maneira de fazer isso permite que você aponte apenas para um estilo e NÃO para o tema TODOS os botões do seu aplicativo sejam iguais.
Em themes.xml, adicione um 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>

Agora em styles.xml, adicione

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

Agora, no seu layout, aponte para o ESTILO no seu botão

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

1

ATUALIZAR

Use a biblioteca de suporte de design (23.2.0) e os appcompatwidgets conforme abaixo

Na Biblioteca de suporte do Android 22.1 :

Isso é feito automaticamente ao inflar layouts - substituindo Button por AppCompatButton, TextView por AppCompatTextView etc. para garantir que cada um possa suportar tinturas. Nesta versão, esses widgets com reconhecimento de tonalidade agora estão disponíveis ao público, permitindo que você continue com o suporte de tonalidade, mesmo que precise subclassificar um dos widgets suportados.

A lista completa de widgets com reconhecimento de tonalidade:

AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView

Projeto de material para dispositivos pré-pirulito :

O AppCompat (também conhecido como ActionBarCompat) começou como um backport da API ActionBar do Android 4.0 para dispositivos em execução no Gingerbread, fornecendo uma camada de API comum sobre a implementação do backport e a implementação da estrutura. O AppCompat v21 fornece uma API e um conjunto de recursos atualizados com o Android 5.0



1

Se você deseja usar o estilo AppCompat como Widget.AppCompat.Button , Base.Widget.AppCompat.Button.Colored , etc., será necessário usar esses estilos com visualizações compatíveis da biblioteca de suporte.

O código abaixo não funciona para dispositivos pré-lolipop:

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

Você precisa usar o AppCompatButton para ativar os estilos do AppCompat:

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

2
Os widgets compatíveis com aplicativos não são usados ​​automaticamente ao inflar layouts XML? Eu acredito que ImageViewé substituído AppCompatImageViewe deve ser o mesmo com todos os widgets, que têm a AppCompatversão correspondente .
precisa saber é o seguinte

Não, se você não segmentar a última versão de destino, precisará definir android.support.v7.widget.AppCompatImageViewexplicitamente.
farukcankaya

O que você quer dizer com last target version@power?
precisa saber é

1

Eu uso isso. Efeito cascata e botão clique em trabalho de sombra.

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>

Botão no layout:

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

0

Na verdade, eu não queria uma alteração nos meus estilos de botão personalizados, mas infelizmente eles não estavam mais funcionando.

Meu aplicativo tem uma minSdkVersion de 9 e tudo funcionou antes.

Não sei por que, mas desde que removi o andróide: antes do buttonStyle parece funcionar novamente

now = working:

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

before = apenas botões de material cinza:

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

Não tenho uma pasta especial para a versão mais recente do Android, já que meus botões são bastante planos e devem ter a mesma aparência em todas as versões do Android.

Talvez alguém possa me dizer por que tive que remover o "android:" O ImageButton ainda está trabalhando com "android:"

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

0

Depois de dois dias procurando respostas, o tema do botão não funcionou para mim na API <21.

Minha única solução é substituir o AppCompatButton tintométrico não apenas pelo tema base do aplicativo "colorButtonNormal", mas também pela visualização backgroundTint como esta:

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

Você pode definir a cor do seu botão assim:

<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

Esta resposta SO me ajudou a chegar a uma resposta https://stackoverflow.com/a/30277424/3075340

Eu uso esse método utilitário para definir a tonalidade de fundo de um botão. Funciona com dispositivos pré-pirulito:

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

}

Como usar no código:

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

Dessa forma, você não precisa especificar um ColorStateList se quiser apenas alterar a tonalidade do plano de fundo e nada mais, além de manter os efeitos bonitos dos botões e o que não.


0

Defino android:textColorcomo @nullno meu tema de botão e isso ajuda.

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" />

Agora, a cor do texto do botão é colorAccentdefinida emAppTheme

<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 você usar o kotlin, poderá ver Todos os atributos do MaterialButton são suportados. Não use o atributo android: background. O MaterialButton gerencia seu próprio drawable de segundo plano e definir um novo plano de fundo significa que a cor desabilitada do botão Material não pode mais garantir que os novos atributos introduzidos funcionem corretamente. Se o plano de fundo padrão for alterado, o Botão Material não poderá garantir um comportamento bem definido. At 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
            }
        }
    }
}

Em 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>

recurso: Exemplo de mudança de cor do botão Material


0

se você quiser fazer isso via código em qualquer cor, use o seguinte:

DrawableCompat.setTintList(button.getBackground(), ColorStateList.valueOf(yourColor));
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.