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>

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


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.


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


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.


12

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

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

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>


1

Usei este código para isso:

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

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