Odpowiedzi:
Generalnie nie można programowo zmieniać stylów; możesz ustawić wygląd ekranu, części układu lub pojedynczego przycisku w układzie XML za pomocą motywów lub stylów . Motywy można jednak stosować programowo .
Istnieje również coś, StateListDrawable
co pozwala zdefiniować różne drawables dla każdego stanu, w którym Button
możesz się znajdować, niezależnie od tego, czy jest skoncentrowany, wybrany, wciśnięty, wyłączony i tak dalej.
Na przykład, aby przycisk zmieniał kolor po naciśnięciu, możesz zdefiniować plik XML o nazwie res/drawable/my_button.xml
katalog w następujący sposób:
<?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>
Następnie możesz zastosować ten selektor do a Button
, ustawiając właściwość android:background="@drawable/my_button"
.
style
atrybutu Androida , ale możesz programowo ustawić tło w Button
taki sam sposób, jak możesz, z dowolnym innym widokiem, jeśli to wystarczy. Ponadto, jako Button
dziedziczenie z TextView
, możesz zmieniać właściwości tekstu. Wystarczy spojrzeć na dokumentację API dla tych elementów ... developer.android.com/reference/android/view/
Po pierwsze, nie musisz używać inflatera układu, aby utworzyć prosty przycisk. Możesz po prostu użyć:
button = new Button(context);
Jeśli chcesz nadać styl przyciskowi, masz dwie możliwości: najprostsza to po prostu określenie wszystkich elementów w kodzie, jak sugeruje wiele innych odpowiedzi:
button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
Inną opcją jest zdefiniowanie stylu w XML i zastosowanie go do przycisku. W ogólnym przypadku możesz użyć ContextThemeWrapper
do tego:
ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);
Aby zmienić atrybuty związane z tekstem w TextView (lub jego podklasach, takich jak Button), istnieje specjalna metoda:
button.setTextAppearance(context, R.style.MyTextStyle);
Ten ostatni nie może być użyty do zmiany wszystkich atrybutów; na przykład, aby zmienić dopełnienie, musisz użyć pliku ContextThemeWrapper
. Ale dla koloru, rozmiaru tekstu itp. Możesz użyć setTextAppearance
.
Tak, możesz użyć na przykład w przycisku
Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);
Możesz tworzyć atrybuty stylu, takie jak:
Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);
zamiast:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
style="?android:attr/buttonBarButtonStyle"
/>
Jeśli korzystasz z biblioteki pomocy technicznej, możesz po prostu użyć
TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);
dla TextViews i Buttons. Dla pozostałych widoków są podobne klasy :-)
Dla każdego, kto szuka materialnej odpowiedzi, zobacz ten wpis SO: Przyciski kolorowania w systemie Android z Material Design i AppCompat
Użyłem kombinacji tej odpowiedzi, aby ustawić domyślny kolor tekstu przycisku na biały dla mojego przycisku: https://stackoverflow.com/a/32238489/3075340
Następnie ta odpowiedź https://stackoverflow.com/a/34355919/3075340, aby programowo ustawić kolor tła. Kod do tego to:
ViewCompat.setBackgroundTintList(your_colored_button,
ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
your_colored_button
może to być zwykły Button
przycisk lub przycisk AppCompat, jeśli chcesz - przetestowałem powyższy kod z obydwoma typami przycisków i działa.
EDYCJA: Odkryłem, że urządzenia pre-Lollipop nie działają z powyższym kodem. Zobacz ten post, aby dowiedzieć się, jak dodać obsługę urządzeń sprzed wersji Lollipop: https://stackoverflow.com/a/30277424/3075340
Zasadniczo zrób to:
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);
}
W zależności od atrybutów stylu, które chcesz zmienić, możesz skorzystać z biblioteki Paryża:
Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);
Obsługiwanych jest wiele atrybutów, takich jak tło, wypełnienie, textSize, textColor itp.
Zastrzeżenie: jestem autorem biblioteki.
Odpowiedź udzielona przez @Dayerman i @h_rules jest właściwa. Aby podać rozbudowany przykład z kodem, w folderze do rysowania utwórz plik xml o nazwie 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>
Następnie w Javie
((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);
Spowoduje to ustawienie właściwości przycisku na wyłączone i ustawienie koloru na srebrny.
[Kolor jest zdefiniowany w color.xml jako:
<resources>
<color name="silver">#C0C0C0</color>
</resources>
W czasie działania wiesz, jaki styl chcesz mieć przycisk. Tak więc wcześniej, w XML w folderze układu, możesz mieć wszystkie gotowe przyciski z potrzebnymi stylami. Więc w folderze układu możesz mieć plik o nazwie: button_style_1.xml. Zawartość tego pliku może wyglądać następująco:
<?xml version="1.0" encoding="utf-8"?>
<Button
android:id="@+id/styleOneButton"
style="@style/FirstStyle" />
Jeśli pracujesz z fragmentami, to w onCreateView nadmuchujesz ten przycisk, na przykład:
Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
gdzie container to kontener ViewGroup skojarzony z metodą onCreateView, którą nadpisujesz podczas tworzenia fragmentu.
Potrzebujesz jeszcze dwóch takich przycisków? Tworzysz je w ten sposób:
Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Możesz dostosować te przyciski:
secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");
Następnie dodajesz dostosowane, stylizowane przyciski do kontenera układu, który również zawyżasz w metodzie onCreateView:
_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);
_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);
I tak można dynamicznie pracować ze stylizowanymi przyciskami.
Zrobiłem do tego interfejs pomocniczy, używając wzoru uchwytu.
public interface StyleHolder<V extends View> {
void applyStyle(V view);
}
Teraz dla każdego stylu, którego chcesz używać pragmatycznie, po prostu zaimplementuj interfejs, na przykład:
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);
}
}
Zadeklaruj styl w swoim attrs.xml
, stylizowany na ten przykład to:
<declare-styleable name="ButtonStyleHolder">
<attr name="android:background" />
<attr name="android:textSize" />
<attr name="android:textColor" />
</declare-styleable>
Oto styl zadeklarowany w 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>
I wreszcie implementacja posiadacza stylu:
Button btn = new Button(context);
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);
Uważam, że jest to bardzo pomocne, ponieważ można go łatwo ponownie wykorzystać i zachowuje kod czysty i rozwlekły, zalecałbym używanie tego tylko jako zmiennej lokalnej, abyśmy mogli pozwolić odśmiecaczowi pamięci wykonać swoją pracę, gdy skończymy ustawiać wszystkie style .
Ostatnio miałem ten sam problem. oto jak to rozwiązałem.
<?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>
Dzięki !