Pergunta

Eu gostaria de mudar a cor de um botão Android padrão ligeiramente, a fim de melhor corresponder a marca de um cliente.

A melhor maneira que eu encontrei para fazer isso até agora é mudar drawable do Button ao drawable localizado na 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>

Mas fazer isso exige que eu realmente criar três drawables diferentes para cada botão que pretende personalizar (um para o botão em repouso, um quando focado, e um quando pressionado). Isso parece mais complicado e não-seca do que eu preciso.

Tudo o que eu realmente quero fazer é aplicar algum tipo de transformação de cor para o botão. Existe uma maneira mais fácil de ir sobre como alterar a cor de um botão do que eu estou fazendo?

Foi útil?

Solução

Eu descobri que tudo isso pode ser feito em um arquivo com bastante facilidade. Coloque algo como o seguinte código em um arquivo chamado custom_button.xml e depois background="@drawable/custom_button" conjunto na sua opinião botão:

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

Outras dicas

Na sequência da resposta de Tomasz, você pode também definir programaticamente a sombra do botão inteiro usando o modo de multiplicar PorterDuff. Isso vai mudar a cor do botão em vez de apenas o matiz.

Se você começar com um botão sombreado cinza padrão:

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

lhe dará um botão sombreado vermelho,

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

lhe dará um botão com sombra verde etc., onde o primeiro valor é a cor em formato hexadecimal.

Ele funciona através da multiplicação do valor de cor botão atual pelo seu valor de cor. Eu tenho certeza que há também muito mais você pode fazer com estes modos.

Mike, você pode estar interessado em filtros de cor.

Um exemplo:

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

tentar isso para conseguir a cor desejada.

Esta é a minha solução que funciona perfeitamente começando a partir de API 15 . Esta solução mantém todos os efeitos Clique no botão padrão, como RippleEffect material. Eu não testei-o em APIs mais baixos, mas deve funcionar.

Tudo que você precisa fazer, é:

1) Criar um estilo que só muda colorAccent:

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

Eu recomendo usar ThemeOverlay.AppCompat ou o seu principal AppTheme como pai, para manter o resto de seus estilos.

2) Adicionar estas duas linhas para seu widget button:

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

Às vezes o seu novo colorAccent não está mostrando no Android Estúdio Preview, mas quando você iniciar o seu aplicativo no telefone, a cor será alterado.


Button Amostra Widget

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

 Botão de amostra com cor personalizada

Agora também é possível usar appcompat-v7 é AppCompatButton com o atributo 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"/>

Eu gosto da sugestão filtro de cor nas respostas anteriores de @conjugatedirection e @Tomasz; No entanto, descobri que o código fornecido até agora não foi tão facilmente aplicado como eu esperava.

Em primeiro lugar, não foi mencionado onde para aplicar e limpar o filtro de cor. É possível que haja outros bons lugares para fazer isso, mas o que me veio à mente para mim foi um OnTouchListener .

De minha leitura da pergunta inicial, a solução ideal seria aquela que não envolve quaisquer imagens. A resposta aceita usando custom_button.xml de @emmby é provavelmente um ajuste melhor do que os filtros de cor, se esse é o seu objetivo. No meu caso, eu estou começando uma imagem png de um designer de interface do usuário do que o botão é suposto a aparência com. Se eu definir o fundo botão para esta imagem, o feedback destaque padrão é perdida completamente. Este código substitui esse comportamento com um efeito escurecimento programático.

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

Eu extraí isto como uma classe separada para aplicação em vários botões -. Como classe interna anônima apenas para obter a ideia

Se você está fazendo botões coloridos com XML pode tornar o código um pouco mais limpo, especificando o focado e estado pressionado em um arquivo separado e reutilizá-los. Meu botão olhares verdes como este:

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

A solução mais curta que está trabalhando com qualquer versão Android:

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

Notas / Requisitos :

  • Use o namespace app: e não do namespace android:!
  • versão appcompat> 24.2.0

    dependências { compilação 'com.android.support:appcompat-v7:25.3.1' }

Explicação : enter descrição da imagem aqui

Eu estou usando esta abordagem

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>

Como você pode ver acima, eu estou usando um estilo personalizado para o meu botão. A cor do botão corresponde à cor de destaque. Acho isso uma abordagem muito melhor do que a criação android:background como eu não perderá o efeito cascata Google fornece.

Há uma maneira muito mais fácil agora: android-holo-colors.com

Ele permitirá que você alterar as cores de todos os drawables holo (botões, spinners, ...) facilmente. Você seleciona a cor e, em seguida, baixar um arquivo zip contendo drawables para todas as resoluções.

Use-o desta forma:

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

Em uso <Button> android:background="#33b5e5". ou melhor android:background="@color/navig_button"

O DroidUX biblioteca componente tem um ColorButton Widget cuja cor pode ser alterado facilmente, tanto por meio de definição de XML e programaticamente em tempo de execução, assim você pode até mesmo permitir que o usuário para definir o botão de cor / tema se seu aplicativo permite que ele.

Você também pode usar esta ferramenta online para personalizar o botão http://angrytools.com/android/button/ e uso android:background="@drawable/custom_btn" para definir o botão personalizado em seu layout.

Você pode definir tema do seu botão para este

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

Uma maneira fácil é apenas para definir uma classe de botão personalizado que aceita todas as propriedades que você deseja, como raio, inclinação, cor pressionado, cor normal etc. e depois é só usar isso em seus layouts XML em vez de criar o fundo usando XML. Uma amostra é aqui

Isto é extremamente útil se você tem um monte de botões com as mesmas propriedades como o raio, selecionado cor etc. Você pode personalizar seu botão herdado para lidar com essas propriedades adicionais.

Resultado (Sem seletor de fundo foi usado).

Button normal

Imagem Normal

botão pressionado

enter descrição da imagem aqui

O que eu faço um botão com estilo diferente, que funciona muito bem é a subclasse do objeto Button e aplicar um filtro de cor. Isso também alças habilitado e estados com deficiência através da aplicação de um alfa para o botão.

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

}

Os valores \ 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>

então:

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

resultado

Por diretrizes de design de material, você precisa usar o estilo como o código abaixo

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

e no layout adicionar essa propriedade para o botão

    android:theme="@style/MyButton"

É simples .. adicionar esta dependência em seu projeto e criar um botão com 1. Qualquer forma 2. Qualquer cor 3. Qualquer fronteira 4. Com efeitos relevantes

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" />
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top