Como Customizar a Cor de Fundo de um Botão no Android

Neste post vou demonstrar como configurar a cor de fundo de um botão utilizando duas técnicas diferentes. Uma utilizando figuras com cor em degradê, para dar o efeito do botão sendo pressionado, e outra utilizando o mesmo efeito degradê só que, fazendo a configuração do botão utilizando um arquivo xml.

Para este exemplo criei um projeto com dois botões com cor em degradê como demonstrado na Figura 1.

background1
Figura 1
Para montar o layout dois dois botões foi utilizado o seguinte código no arquivo main.xml (Listagem 1):

Listagem 1:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 
    <!-- View utilizada como separador -->
    <View
        android:layout_width="fill_parent" 
        android:layout_height="10sp"        
        android:id="@+id/view1"
     />
 
    <Button 
        android:id="@+id/btnJpg"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/view1"
        android:text="Design por Figura Jpg"
        android:background="@drawable/botao_azul_selector"
    />
    
        <!-- View utilizada como separador -->
    <View
        android:layout_width="fill_parent" 
        android:layout_height="10sp"        
        android:id="@+id/view2"
        android:layout_below="@+id/btnJpg"
     />
    
    <Button 
        android:id="@+id/btnXml"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/view2"
        android:text="Design por Arquivo Xml"
        android:background="@drawable/botao_verde_selector"
    />    
</RelativeLayout>


No primeiro botão btnJpg foi utilizado como cor de fundo duas figuras em degradê uma para quando o botão for pressionado e outra para quando o botão for solto. É necessário utilizar duas figuras para dar o efeito dinâmico do botão estar sendo pressionado.

Para configurar este efeito utilizei um recurso chamado de StateListDrawable que é um arquivo xml onde podemos configurar figuras diferentes para cada estado, por exemplo de um botão.
Este arquivo xml deve ser colocado em um diretório \drawable. O arquivo para configurar o primeiro botão é o botão_azul_selector (Listagem 2), configurado no atributo android:background="@drawable/botao_azul_selector".

Listagem 2:
<?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/botao_azul_on"
    />
    <item 
        android:drawable="@drawable/botao_azul_off"
    />
</selector>


No estado android:state_pressed foi utilizada a figura botao_azul_on para representar o botão quando pressionado e a figura botao_azul_off para representar o botão no estado não pressionado. As figuras do botão devem estar em um diretório \drawable.

No segundo botão btnXml foi utilizada uma outra técnica de configurar a cor de fundo do botão. O princípio é o mesmo, foi utilizado um arquivo Xml para configurar a aparência do botão em cada um dos estados (pressionado ou não), só que desta vez ao invés de utilizar figuras .jpg, foram utilizadas tags para construir a forma geométrica do botão. O arquivo botao_verde_selector também deve ser colocado em um diretório \drawable (Listagem 3):

Listagem 3:
<?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/verde_claro" 
                android:endColor="@color/verde_escuro"
                android:angle="270" />
            <stroke
                android:width="1dp"
                android:color="@color/verde_escuro" />
            <corners
                android:radius="10dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
    <item>
       <shape>
            <gradient
                android:startColor="@color/verde_escuro" 
                android:endColor="@color/verde_claro"
                android:angle="270" />
            <stroke
                android:width="1dp"
                android:color="@color/verde_escuro" /> 
            <corners
                android:radius="10dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

A aparência do botão verde é construída através da tag de forma <shape> cujo default é o retângulo. Dentro desta tag temos a tag <gradient> que define a cor degradê, a tag <stroke> que define a largura e a cor do contorno do botão, a tag <corners> que define o ângulo da borda arredondada do nosso botão e a tag <padding> que define o posicionamento do conteúdo e não da forma geométrica do botão.

Observe que foram criadas duas tags <item>, uma para o estado pressionado do botão e outra para o estado default do botão.
Para rodar a aplicação foi criada a Activity Principal (Listagem 4):

Listagem 4:
public class Principal extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}