Risposte:
In genere non è possibile modificare gli stili a livello di programmazione; è possibile impostare l'aspetto di una schermata, di una parte di un layout o di un singolo pulsante nel layout XML utilizzando temi o stili . I temi possono, tuttavia, essere applicati a livello di codice .
Esiste anche qualcosa come un StateListDrawable
che ti consente di definire diversi drawables per ogni stato in cui puoi trovarti Button
, che sia focalizzato, selezionato, premuto, disabilitato e così via.
Ad esempio, per fare in modo che il tuo pulsante cambi colore quando viene premuto, puoi definire un file XML chiamato res/drawable/my_button.xml
directory come questo:
<?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>
È quindi possibile applicare questo selettore a Button
impostando la proprietà android:background="@drawable/my_button"
.
style
attributo Android , ma puoi impostare a livello di codice lo sfondo di un Button
come puoi con qualsiasi altra vista, se questo è sufficiente. Inoltre, come Button
eredita da TextView
, puoi modificare le proprietà del testo. Basta guardare la documentazione API per questi elementi ... developer.android.com/reference/android/view/…
Prima di tutto, non è necessario utilizzare un inflater di layout per creare un semplice Button. Puoi semplicemente usare:
button = new Button(context);
Se vuoi dare uno stile al pulsante hai 2 scelte: la più semplice è semplicemente specificare tutti gli elementi nel codice, come suggeriscono molte altre risposte:
button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
L'altra opzione è definire lo stile in XML e applicarlo al pulsante. Nel caso generale, puoi usare a ContextThemeWrapper
per questo:
ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);
Per modificare gli attributi relativi al testo su un TextView (o sulle sue sottoclassi come Button) esiste un metodo speciale:
button.setTextAppearance(context, R.style.MyTextStyle);
Quest'ultimo non può essere utilizzato per modificare tutti gli attributi; ad esempio per modificare il padding è necessario utilizzare un file ContextThemeWrapper
. Ma per il colore del testo, la dimensione, ecc. Puoi usare setTextAppearance
.
Sì, puoi usare ad esempio in un pulsante
Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);
Puoi eseguire attributi di stile in questo modo:
Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);
al posto di:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
style="?android:attr/buttonBarButtonStyle"
/>
Se stai usando la libreria di supporto, puoi semplicemente usare
TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);
per TextView e pulsanti. Ci sono classi simili per il resto di Views :-)
Per chiunque cerchi una risposta Material, vedere questo post SO: Colorare i pulsanti in Android con Material Design e AppCompat
Ho usato una combinazione di questa risposta per impostare il colore del testo predefinito del pulsante su bianco per il mio pulsante: https://stackoverflow.com/a/32238489/3075340
Quindi questa risposta https://stackoverflow.com/a/34355919/3075340 per impostare a livello di codice il colore di sfondo. Il codice per questo è:
ViewCompat.setBackgroundTintList(your_colored_button,
ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
your_colored_button
può essere solo un Button
pulsante normale o AppCompat, se lo desideri: ho testato il codice sopra con entrambi i tipi di pulsanti e funziona.
EDIT: ho scoperto che i dispositivi pre-lollipop non funzionano con il codice sopra. Guarda questo post su come aggiungere il supporto per i dispositivi pre-lecca-lecca: https://stackoverflow.com/a/30277424/3075340
Fondamentalmente fai questo:
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);
}
A seconda degli attributi di stile che desideri modificare, potresti essere in grado di utilizzare la libreria di Parigi:
Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);
Sono supportati molti attributi come background, padding, textSize, textColor, ecc.
Disclaimer: ho creato la libreria.
La risposta di @Dayerman e @h_rules è giusta. Per fornire un esempio elaborato con il codice, nella cartella drawable, creare un file xml chiamato 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>
Quindi in Java,
((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);
Ciò imposterà la proprietà del pulsante su disabilitato e il colore verrà impostato su argento.
[Il colore è definito in color.xml come:
<resources>
<color name="silver">#C0C0C0</color>
</resources>
In fase di esecuzione, sai quale stile vuoi che abbia il tuo pulsante. Quindi in anticipo, in xml nella cartella del layout, puoi avere tutti i pulsanti pronti per l'uso con gli stili di cui hai bisogno. Quindi nella cartella del layout, potresti avere un file chiamato: button_style_1.xml. Il contenuto di quel file potrebbe essere simile a:
<?xml version="1.0" encoding="utf-8"?>
<Button
android:id="@+id/styleOneButton"
style="@style/FirstStyle" />
Se stai lavorando con i frammenti, allora in onCreateView gonfi quel pulsante, come:
Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
dove container è il contenitore ViewGroup associato al metodo onCreateView che sostituisci durante la creazione del frammento.
Hai bisogno di altri due pulsanti di questo tipo? Li crei in questo modo:
Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Puoi personalizzare questi pulsanti:
secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");
Quindi aggiungi i tuoi pulsanti personalizzati e stilizzati al contenitore di layout che hai anche gonfiato nel metodo onCreateView:
_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);
_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);
Ed è così che puoi lavorare dinamicamente con i pulsanti stilizzati.
Ho creato un'interfaccia di supporto per questo utilizzando il modello di supporto.
public interface StyleHolder<V extends View> {
void applyStyle(V view);
}
Ora, per ogni stile che desideri utilizzare pragmaticamente, implementa semplicemente l'interfaccia, ad esempio:
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);
}
}
Dichiara uno stylable nel tuo attrs.xml
, lo stile per questo esempio è:
<declare-styleable name="ButtonStyleHolder">
<attr name="android:background" />
<attr name="android:textSize" />
<attr name="android:textColor" />
</declare-styleable>
Ecco lo stile dichiarato in 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 infine l'implementazione dello style holder:
Button btn = new Button(context);
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);
L'ho trovato molto utile in quanto può essere facilmente riutilizzato e mantiene il codice pulito e dettagliato, consiglierei di usarlo solo come variabile locale in modo da poter consentire al garbage collector di fare il suo lavoro una volta che abbiamo finito di impostare tutti gli stili .
Di recente ho affrontato lo stesso problema. ecco come l'ho risolto.
<?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>
Grazie !