Cara menyetel atribut gaya secara terprogram dalam tampilan

107

Saya mendapatkan tampilan dari XML dengan kode di bawah ini:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);

Saya ingin menetapkan "gaya" untuk tombol bagaimana saya bisa melakukannya di java karena saya ingin menggunakan beberapa gaya untuk setiap tombol yang akan saya gunakan.

Lint_
sumber

Jawaban:

52

Umumnya Anda tidak dapat mengubah gaya secara terprogram; Anda bisa menyetel tampilan layar, atau bagian dari tata letak, atau tombol individual dalam tata letak XML Anda menggunakan tema atau gaya . Namun, tema dapat diterapkan secara terprogram .

Ada juga StateListDrawableyang memungkinkan Anda menentukan drawable yang berbeda untuk setiap status tempat Anda Buttonberada, apakah difokuskan, dipilih, ditekan, dinonaktifkan, dan sebagainya.

Misalnya, agar tombol Anda berubah warna saat ditekan, Anda dapat menentukan file XML yang disebut res/drawable/my_button.xmldirektori seperti ini:

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

Anda kemudian dapat menerapkan pemilih ini ke a Buttondengan menyetel properti android:background="@drawable/my_button".

Christopher Orr
sumber
4
Masalah saya adalah saya memuat data dari layanan web yang menjelaskan info tombol saya. Tombol harus memiliki gaya yang berbeda berdasarkan kategori tempat tombol tersebut berada. Itulah mengapa saya ingin mengatur gaya secara dinamis.
Lint_
3
Anda tidak dapat mengubah styleatribut Android , tetapi Anda dapat secara terprogram mengatur latar belakang Buttonseperti yang Anda bisa dengan tampilan lain, jika itu sudah cukup. Selain itu, sebagai Buttonwarisan dari TextView, Anda dapat mengubah properti teks. Lihat saja dokumentasi API untuk item ini ... developer.android.com/reference/android/view/…
Christopher Orr
Saya baru saja berpikir untuk melakukan itu, tepat sebelum memeriksa apakah saya punya jawaban baru. Terima kasih banyak.
Lint_
5
Apakah tidak mungkin membuat gaya untuk tombol yang menentukan ukuran teks, margin, dll. Dan kemudian menerapkannya ke tombol secara programatik. Mungkinkah mengatakan jika saya memiliki enam tombol yang ingin memiliki gaya yang sama?
Beruang
atribut mana yang bisa kita kembangkan? bisakah kita meningkatkan margin, padding?
Android Man
49

Pertama-tama, Anda tidak perlu menggunakan inflater tata letak untuk membuat Tombol sederhana. Anda bisa menggunakan:

button = new Button(context);

Jika Anda ingin memberi gaya pada tombol, Anda memiliki 2 pilihan: yang paling sederhana adalah menentukan semua elemen dalam kode, seperti yang disarankan oleh banyak jawaban lain:

button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

Opsi lainnya adalah menentukan gaya dalam XML, dan menerapkannya ke tombol. Dalam kasus umum, Anda dapat menggunakan a ContextThemeWrapperuntuk ini:

ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);

Untuk mengubah atribut terkait teks pada TextView (atau subclassnya seperti Button) ada metode khusus:

button.setTextAppearance(context, R.style.MyTextStyle);

Yang terakhir ini tidak dapat digunakan untuk mengubah semua atribut; misalnya untuk mengganti padding Anda perlu menggunakan aContextThemeWrapper . Tetapi untuk warna teks, ukuran, dll. Anda dapat menggunakan setTextAppearance.

bitstra
sumber
1
Luar biasa. ContextThemeWrapper - adalah apa yang sudah lama saya cari.
Ayaz Alifov
Ini bekerja dengan luar biasa. Telah mencari solusi ini untuk sementara waktu.
jasonjwwilliams
14

Ya, Anda dapat menggunakan misalnya di sebuah tombol

Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);
Dayerman
sumber
5
Itu akan mengatur latar belakang tetapi gaya dapat menentukan lebih dari sekedar latar belakang. Banyak Tampilan (termasuk Tombol) tampaknya memiliki konstruktor yang menggunakan ID gaya sebagai parameter. Namun, saya mengalami masalah untuk membuatnya bekerja untuk saya - tombol muncul sebagai teks tanpa batas atau apa pun. Yang mungkin saya lakukan adalah membuat tata letak dengan hanya sebuah tombol di dalamnya (dengan gaya yang ditentukan), memekarkan tata letak itu, lalu menyetel teks tombol dan yang lainnya.
spaaarky21
11

Anda dapat melakukan atribut gaya seperti ini:

Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);

di tempat:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    style="?android:attr/buttonBarButtonStyle"

    />
Kristy Welsh
sumber
7
Jawaban yang bagus mengingat sebuah tombol akan dibuat. Akan menyenangkan untuk melihat bagaimana melakukannya untuk tombol yang ada.
Katalis Kualitas
Lihat jawabannya dari cesards.
Kristy Welsh
10

Jika Anda menggunakan pustaka Dukungan, Anda cukup menggunakan

TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);

untuk TextView dan Buttons. Ada kelas serupa untuk Tampilan lainnya :-)

cesards
sumber
Paket R mana yang perlu Anda gunakan untuk mendapatkan gaya ini?
htafoya
6

Untuk siapa pun yang mencari jawaban Material lihat posting SO ini: Tombol Mewarnai di Android dengan Desain Material dan AppCompat

Saya menggunakan kombinasi jawaban ini untuk menyetel warna teks default tombol menjadi putih untuk tombol saya: https://stackoverflow.com/a/32238489/3075340

Kemudian jawaban ini https://stackoverflow.com/a/34355919/3075340 untuk mengatur warna latar belakang secara terprogram. Kode untuk itu adalah:

ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));

your_colored_buttonbisa berupa Buttontombol biasa atau AppCompat jika Anda mau - Saya menguji kode di atas dengan kedua jenis tombol dan berhasil.

EDIT: Saya menemukan bahwa perangkat pra-lollipop tidak berfungsi dengan kode di atas. Lihat posting ini tentang cara menambahkan dukungan untuk perangkat pra-lollipop: https://stackoverflow.com/a/30277424/3075340

Pada dasarnya lakukan ini:

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);
}
Mikro
sumber
6

Bergantung pada atribut gaya apa yang ingin Anda ubah, Anda mungkin dapat menggunakan perpustakaan Paris:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);

Banyak atribut seperti background, padding, textSize, textColor, dll yang didukung.

Penafian: Saya yang menulis perpustakaan.

Nathanael
sumber
5

Jawaban @Dayerman dan @h_rules benar. Untuk memberikan contoh yang diuraikan dengan kode, Dalam folder drawable, buat file xml bernama 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>

Lalu di Jawa,

((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);

Ini akan menyetel properti tombol menjadi nonaktif dan menyetel warna menjadi perak.

[Warna didefinisikan dalam color.xml sebagai:

<resources>

    <color name="silver">#C0C0C0</color>

</resources>
biniam
sumber
4
@Pacerier: pertanyaannya tidak mengatakan itu sama sekali. Itu ambigu apakah gayanya XML atau di java. Ini hanya menanyakan bagaimana mengatur gaya secara terprogram.
Harvey
3

Saat runtime, Anda tahu gaya tombol yang Anda inginkan. Jadi sebelumnya, di xml di folder layout, Anda dapat memiliki semua tombol siap pakai dengan gaya yang Anda butuhkan. Jadi di folder tata letak, Anda mungkin memiliki file bernama: button_style_1.xml. Konten file itu mungkin terlihat seperti:

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:id="@+id/styleOneButton"
    style="@style/FirstStyle" />

Jika Anda bekerja dengan fragmen, maka di onCreateView Anda memekarkan tombol itu, seperti:

Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

di mana penampung adalah penampung ViewGroup yang terkait dengan metode onCreateView yang Anda ganti saat membuat fragmen.

Butuh dua tombol lagi? Anda membuatnya seperti ini:

Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

Anda dapat menyesuaikan tombol-tombol itu:

secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");

Kemudian Anda menambahkan tombol yang disesuaikan dan bergaya ke wadah tata letak yang juga Anda tingkatkan dalam metode onCreateView:

_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);

_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);

Dan begitulah cara Anda dapat bekerja secara dinamis dengan tombol bergaya.

Jerry Frost
sumber
0

Saya membuat antarmuka pembantu untuk ini menggunakan pola pemegang.

public interface StyleHolder<V extends View> {
    void applyStyle(V view);
}

Sekarang untuk setiap gaya yang ingin Anda gunakan secara pragmatis cukup terapkan antarmuka, misalnya:

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

Deklarasikan gaya di Anda attrs.xml, gaya untuk contoh ini adalah:

<declare-styleable name="ButtonStyleHolder">
    <attr name="android:background" />
    <attr name="android:textSize" />
    <attr name="android:textColor" />
</declare-styleable>

Berikut adalah gaya yang dideklarasikan 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>

Dan akhirnya penerapan pemegang gaya:

Button btn = new Button(context);    
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);

Saya menemukan ini sangat membantu karena dapat dengan mudah digunakan kembali dan menjaga kode tetap bersih dan bertele-tele, saya akan merekomendasikan menggunakan ini hanya sebagai variabel lokal sehingga kami dapat mengizinkan pengumpul sampah untuk melakukan tugasnya setelah kami selesai dengan mengatur semua gaya .

Kostyantin 2216
sumber
-1

Saya menghadapi masalah yang sama baru-baru ini. inilah cara saya menyelesaikannya.

<?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>
  • Saya menggunakan LinearLayout dengan android: weightSum = "2"
  • Saya memberikan dua elemen anak android: layout_weight = "1" (Saya memberikan masing-masing 50% dari ruang induk (lebar & tinggi))
  • Dan akhirnya, saya memberi dua elemen anak warna latar belakang yang berbeda untuk mendapatkan efek akhir.

Terima kasih!

dev242
sumber