Respostas:
Geralmente, você não pode alterar estilos de forma programática; você pode definir a aparência de uma tela, ou parte de um layout, ou botão individual em seu layout XML usando temas ou estilos . Os temas podem, no entanto, ser aplicados de forma programática .
Também existe um StateListDrawable
que permite definir drawables diferentes para cada estado em que você Button
pode estar, seja ele focado, selecionado, pressionado, desabilitado e assim por diante.
Por exemplo, para fazer com que seu botão mude de cor quando for pressionado, você pode definir um arquivo XML chamado res/drawable/my_button.xml
diretório como este:
<?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/btn_pressed" />
<item
android:state_pressed="false"
android:drawable="@drawable/btn_normal" />
</selector>
Você pode então aplicar esse seletor a um Button
definindo a propriedade android:background="@drawable/my_button"
.
style
atributo Android , mas pode definir programaticamente o plano de fundo de um Button
como faria com qualquer outra visualização, se isso for suficiente. Além disso, como Button
herda de TextView
, você pode alterar as propriedades do texto. Basta olhar a documentação da API para esses itens ... developer.android.com/reference/android/view/…
Em primeiro lugar, você não precisa usar um inflador de layout para criar um botão simples. Você pode apenas usar:
button = new Button(context);
Se quiser estilizar o botão, você tem 2 opções: a mais simples é apenas especificar todos os elementos no código, como muitas das outras respostas sugerem:
button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
A outra opção é definir o estilo em XML e aplicá-lo ao botão. No caso geral, você pode usar um ContextThemeWrapper
para isso:
ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);
Para alterar os atributos relacionados ao texto em um TextView (ou suas subclasses como Button), existe um método especial:
button.setTextAppearance(context, R.style.MyTextStyle);
Este último não pode ser usado para alterar todos os atributos; por exemplo, para alterar o preenchimento, você precisa usar a ContextThemeWrapper
. Mas para cor de texto, tamanho, etc. você pode usar setTextAppearance
.
Sim, você pode usar, por exemplo, em um botão
Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);
Você pode criar atributos de estilo como:
Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);
no lugar de:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
style="?android:attr/buttonBarButtonStyle"
/>
Se você estiver usando a Biblioteca de suporte, você pode simplesmente usar
TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);
para TextViews e botões. Existem classes semelhantes para o resto das Visualizações :-)
Para quem procura uma resposta material, consulte esta postagem do SO: Botões para colorir no Android com Material Design e AppCompat
Usei uma combinação desta resposta para definir a cor do texto padrão do botão como branco para meu botão: https://stackoverflow.com/a/32238489/3075340
Então esta resposta https://stackoverflow.com/a/34355919/3075340 para definir programaticamente a cor de fundo. O código para isso é:
ViewCompat.setBackgroundTintList(your_colored_button,
ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
your_colored_button
pode ser apenas um normal Button
botão ou AppCompat, se desejar - testei o código acima com os dois tipos de botão e funciona.
EDIT: descobri que os dispositivos pré-pirulito não funcionam com o código acima. Veja esta postagem sobre como adicionar suporte para dispositivos pré-lollipop: https://stackoverflow.com/a/30277424/3075340
Basicamente, faça isso:
Button b = (Button) findViewById(R.id.button);
ColorStateList c = ContextCompat.getColorStateList(mContext, R.color.your_custom_color;
Drawable d = b.getBackground();
if (b instanceof AppCompatButton) {
// appcompat button replaces tint of its drawable background
((AppCompatButton)b).setSupportBackgroundTintList(c);
} 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)
b.setBackgroundTintList(c);
} 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, c);
b.setBackgroundDrawable(d);
}
Dependendo de quais atributos de estilo você gostaria de alterar, você pode usar a biblioteca de Paris:
Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);
Muitos atributos como background, padding, textSize, textColor, etc. são suportados.
Isenção de responsabilidade: eu sou o autor da biblioteca.
A resposta de @Dayerman e @h_rules está certa. Para dar um exemplo elaborado com código, na pasta drawable, crie um arquivo xml chamado button_disabled.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="@color/silver"/>
<corners
android:bottomRightRadius="20dp"
android:bottomLeftRadius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp"/>
</shape>
Então, em Java,
((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);
Isso definirá a propriedade do botão como desativada e definirá a cor como prata.
[A cor é definida em color.xml como:
<resources>
<color name="silver">#C0C0C0</color>
</resources>
Em tempo de execução, você sabe qual estilo deseja que seu botão tenha. Portanto, de antemão, em xml na pasta de layout, você pode ter todos os botões prontos para usar com os estilos que você precisa. Portanto, na pasta de layout, você pode ter um arquivo chamado: button_style_1.xml. O conteúdo desse arquivo pode ser semelhante a:
<?xml version="1.0" encoding="utf-8"?>
<Button
android:id="@+id/styleOneButton"
style="@style/FirstStyle" />
Se você estiver trabalhando com fragmentos, em onCreateView você infla esse botão, como:
Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
onde container é o container ViewGroup associado ao método onCreateView que você substitui ao criar seu fragmento.
Precisa de mais dois desses botões? Você os cria assim:
Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Você pode personalizar esses botões:
secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");
Em seguida, você adiciona seus botões estilizados e personalizados ao contêiner de layout que também aumentou no método onCreateView:
_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);
_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);
E é assim que você pode trabalhar dinamicamente com botões estilizados.
Fiz uma interface auxiliar para isso usando o padrão de suporte.
public interface StyleHolder<V extends View> {
void applyStyle(V view);
}
Agora, para cada estilo que você deseja usar pragmaticamente, apenas implemente a interface, por exemplo:
public class ButtonStyleHolder implements StyleHolder<Button> {
private final Drawable background;
private final ColorStateList textColor;
private final int textSize;
public ButtonStyleHolder(Context context) {
TypedArray ta = context.obtainStyledAttributes(R.style.button, R.styleable.ButtonStyleHolder);
Resources resources = context.getResources();
background = ta.getDrawable(ta.getIndex(R.styleable.ButtonStyleHolder_android_background));
textColor = ta.getColorStateList(ta.getIndex(R.styleable.ButtonStyleHolder_android_textColor));
textSize = ta.getDimensionPixelSize(
ta.getIndex(R.styleable.ButtonStyleHolder_android_textSize),
resources.getDimensionPixelSize(R.dimen.standard_text_size)
);
// Don't forget to recycle!
ta.recycle();
}
@Override
public void applyStyle(Button btn) {
btn.setBackground(background);
btn.setTextColor(textColor);
btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
}
Declare um estilizável em seu attrs.xml
, o estilizável para este exemplo é:
<declare-styleable name="ButtonStyleHolder">
<attr name="android:background" />
<attr name="android:textSize" />
<attr name="android:textColor" />
</declare-styleable>
Aqui está o estilo declarado em styles.xml
:
<style name="button">
<item name="android:background">@drawable/button</item>
<item name="android:textColor">@color/light_text_color</item>
<item name="android:textSize">@dimen/standard_text_size</item>
</style>
E, finalmente, a implementação do suporte de estilo:
Button btn = new Button(context);
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);
Achei isso muito útil, pois pode ser facilmente reutilizado e mantém o código limpo e detalhado, eu recomendaria usar isso apenas como uma variável local para que possamos permitir que o coletor de lixo faça seu trabalho assim que terminarmos de definir todos os estilos .
Eu enfrentei o mesmo problema recentemente. aqui está como eu resolvi isso.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- This is the special two colors background START , after this LinearLayout, you can add all view that have it for main background-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="2"
android:background="#FFFFFF"
android:orientation="horizontal"
>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#0000FF" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#F000F0" />
</LinearLayout>
<!-- This is the special two colors background END-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:text="This Text is centered with a special backgound,
You can add as much elements as you want as child of this RelativeLayout"
android:textColor="#FFFFFF"
android:textSize="20sp" />
</RelativeLayout>
Obrigado !