Como tornar um botão cinza?

103

Eu tenho um botão definido conforme mostrado abaixo. Quando desejo desativá-lo, eu uso my_btn.setEnabled(false), mas também gostaria de desativá- lo. Como eu posso fazer isso?

obrigado

<Button android:id="@+id/buy_btn" style="@style/srp_button" />

style / srp_button

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_default</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:textSize">14sp</item>
    <item name="android:typeface">serif</item>
    <item name="android:paddingLeft">30dp</item>
    <item name="android:paddingRight">30dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
</style>

drawable / btn_default.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/pink" />
    <corners android:radius="6dp" />
</shape>
jul
fonte

Respostas:

57

Você deve fornecer 3 ou 4 estados btn_defaut.xmlcomo seletor.

  1. Estado pressionado
  2. Estado padrão
  3. Estado de foco
  4. Estado habilitado (estado desabilitado com indicação falsa; ver comentários)

Você fornecerá efeito e pano de fundo para os estados de acordo.

Aqui está uma discussão detalhada: Botão Android padrão com uma cor diferente

Adil Soomro
fonte
Portanto, para torná-lo cinza, devo alterar a cor do fundo E a cor do texto no estado desabilitado? Não há como apenas adicionar um primeiro plano transparente?
julho
3
Sim! o que você fornecerá para android:state_disable="true"ele mostrará o estado quando o Botão está desabilitado, a maneira mais fácil e recomendada.
Adil Soomro
e onde posso especificar a cor do texto para o estado desativado? Parece que apenas um fundo pode ser especificado ... Pedi uma nova pergunta para isso: stackoverflow.com/questions/8743584/...
julho
17
Não existe android:state_disable="true", existe? Você está se referindo a android:state_enabled="false"?
caw
@MarcoW .: sim, você está absolutamente correto. Desculpas pelo atributo errado.
Adil Soomro
171

Você também pode fazer com que apareça como desativado, definindo o alfa (tornando-o semitransparente). Isso é especialmente útil se o fundo do botão for uma imagem e você não quiser criar estados para ele.

button.setAlpha(.5f);
button.setClickable(false);

atualização: escrevi a solução acima antes do Kotlin e quando era novato. É mais uma solução "rápida e suja", mas não a recomendo em um ambiente profissional.

Hoje, se eu quisesse uma solução genérica que funcionasse em qualquer botão / visualização sem precisar criar uma lista de estados, eu criaria uma extensão Kotlin.

fun View.disable() {
    getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
    setClickable(false)
}

Em Java, você pode fazer algo semelhante com uma função util estática e só teria que passar a visão como variável. Não é tão limpo, mas funciona.

Siavash
fonte
4
Eu tinha lido que as chamadas para setAlpha são caras na CPU. Alguém pode confirmar?
Ali Kazi de
@AliKazi depende do tipo do seu View. A partir deste post G + : "Se a sua exibição não contém sobreposição de comandos de desenho, setAlpha()é otimizado para longe e nós simplesmente modificar a pintura objetos para aplicar o alfa adequada Isso acontece quando. View.hasOverlappingRendering()Retornos verdade. ImageViewS e TextViews sem drawable fundo são candidatos comuns para este otimização. Se você está nesta situação, use o setAlpha()quanto quiser. ".
Sufian
1
@Sufian Obrigado. Mas para ficar mais seguro, contei com um simples StateListDrawable para cada botão. Como fiz isso, postei como uma nova resposta. Incluí links para onde aprendi que alfa é ruim para o desempenho.
Ali Kazi de
Visualmente hostil ao usuário
Farid
que realmente desativam visualmente a visualização. obrigado @Siavash
Akash Bisariya
54

A solução mais fácil é definir o filtro de cor para a imagem de fundo de um botão como eu vi aqui

Você pode fazer o seguinte:

if ('need to set button disable')
    button.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
else
    button.getBackground().setColorFilter(null);

Espero ter ajudado alguém ...

Woody
fonte
Eu gosto mais dessa abordagem. Obrigado!
nab
2
Essa abordagem tem potencial, mas a cor resultante nem sempre é o que você pensa que será. Por exemplo, um botão laranja com a cor cinza multiplicada resulta em uma cor vermelha escura - não um laranja desbotado.
Alguém em algum lugar
4
talvez Mode.SRC_INdeva ser usado em vez de Multiply. Consulte stackoverflow.com/a/17112876/550471
Someone Somewhere
Isso funciona, mas duas cores quando misturadas se transformam em outra cor
Shamsul Arefin Sajib
Impressionante! Tão limpo.
Milind Chaudhary
21

Todas as respostas fornecidas funcionam bem, mas lembro-me de aprender que usar setAlpha pode ser uma má ideia em termos de desempenho (mais informações aqui ). Portanto, criar um StateListDrawable é uma ideia melhor para gerenciar o estado desabilitado dos botões. Veja como:

Crie um XML btn_blue.xml na pasta res / drawable:

<!-- Disable background -->
<item android:state_enabled="false"
      android:color="@color/md_blue_200"/>

<!-- Enabled background -->
<item android:color="@color/md_blue_500"/>

Crie um estilo de botão em res / values ​​/ styles.xml

<style name="BlueButton" parent="ThemeOverlay.AppCompat">
      <item name="colorButtonNormal">@drawable/btn_blue</item>
      <item name="android:textColor">@color/md_white_1000</item>
</style>

Em seguida, aplique este estilo ao seu botão:

<Button
     android:id="@+id/my_disabled_button"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:theme="@style/BlueButton"/>

Agora, quando você ligar para btnBlue.setEnabled(true)OU, btnBlue.setEnabled(false)as cores do estado mudarão automaticamente.

Ali Kazi
fonte
12

Defina clicável como falso e altere a cor do fundo como:

callButton.setClickable(false);
callButton.setBackgroundColor(Color.parseColor("#808080"));
Saty
fonte
12

Você deve criar um arquivo XML para o botão desativado ( drawable / btn_disable.xml )

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/grey" />
    <corners android:radius="6dp" />
</shape>

E crie um seletor para o botão ( drawable / btn_selector.xml )

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/btn_disable" android:state_enabled="false"/>
    <item android:drawable="@drawable/btn_default" android:state_enabled="true"/>
    <item android:drawable="@drawable/btn_default" android:state_pressed="false" />

</selector>

Adicione o seletor ao seu botão

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_selector</item>
</style>
Willy Chen
fonte
2
Button button = (Button)findViewById(R.id.buy_btn);
button.setEnabled(false);
Leon van Noord
fonte
13
Isso não responde à pergunta.
Quality Catalyst
1

Usei este código para isso:

ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
profilePicture.setColorFilter(filter);
Dominik
fonte
0

Tentei as soluções acima, mas nenhuma delas pareceu funcionar para mim. Eu escolhi a seguinte opção:

<!-- button_color_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_enabled="true"/>
    <item android:color="@color/colorAccentLight" android:state_enabled="false"/>
</selector>
<com.google.android.material.button.MaterialButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/button_color_selector"
                .../>
André Ramon
fonte