Setel gaya untuk TextView secara terprogram

249

Saya mencoba menggunakan TextViewkonstruktor dengan gaya seperti ini:

TextView myText = new TextView(MyActivity.this, null, R.style.my_style);

Namun, ketika saya melakukan ini, tampilan teks tampaknya tidak mengambil gaya (saya memverifikasi gaya dengan mengaturnya pada objek statis).

Saya juga sudah mencoba menggunakan myText.setTextAppearance(MyActivity.this, R.style.my_style)tetapi juga tidak berhasil.

Ben
sumber

Jawaban:

318

Saya tidak percaya Anda dapat mengatur gaya pemrograman. Untuk menyiasatinya, Anda dapat membuat layout file template xml dengan gaya yang ditetapkan, misalnya dalam res / layout membuat tvtemplate.xml seperti dengan konten berikut:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This is a template"
        style="@style/my_style" />

lalu kembangkan ini untuk membuat Instantiate TextView baru Anda:

TextView myText = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);

Semoga ini membantu.

Dan Kilpatrick
sumber
1
Di mana ini menang atas jawaban Dandre Allison adalah bahwa itu tidak memerlukan API v11.
Martin Capodici
2
Mungkin berhasil, tetapi ini tidak masuk akal. Bagaimana itu bisa diatur dengan file xml? jika tidak terprogram . Ada alasan untuk tidak menggunakan file xml, salah satunya adalah saya terbiasa menulis kode untuk membangun UI jadi saya tidak ingin mempelajari cara baru untuk melakukannya karena memori saya terbatas dan saya ingin menyimpan beberapa ruang untuk hal-hal lain.
Iharob Al Asimi
@IharobAlAsimi benar, semua hal bisa dilakukan secara pemrograman, dan LayoutInflater tahu segalanya tentang mengubah XML menjadi objek. Sayangnya, banyak hal seperti itu disembunyikan di bawah API pribadi, dan satu-satunya cara membuat beberapa objek adalah memasok AttributeSet ke konstruktor.
Miha_x64
Tidak seperti semua jawaban lain, ini benar-benar bekerja dengan pemintal jadi bintang emas untuk Anda
Rowan Berry
121

Anda dapat membuat gaya umum dan menggunakannya kembali pada beberapa tayangan teks seperti yang di bawah ini:

textView.setTextAppearance(this, R.style.MyTextStyle);

Sunting: ini merujuk pada Konteks

Shahul3D
sumber
50
Jawaban Anda berfungsi selama semua yang Anda lakukan adalah menguningkan "gaya" teks. Ini tidak berfungsi jika Anda mencoba melakukan hal-hal lain ke TextView seperti menambahkan padding atau margin. Jadi, saya tidak mengatakan Anda salah, tetapi jawaban Anda terbatas. Menggembungkan tampilan saat runtime adalah satu-satunya cara untuk menerapkan gaya komprehensif.
Bill Mote
1
Kedua solusi menggunakan templat yang digembungkan dan menggunakan setTextAppearance masuk akal. Untuk mengatasi masalah padding / margin untuk solusi ke-2, Anda dapat memanggil textView.setLayoutParams (layoutParams)
AlanKley
Metode ini sudah tidak digunakan lagi di API level 23. Gunakan setTextAppearance (int) sebagai gantinya di API 23+.
Sergii
Pastikan versinya setidaknya API 23 (M)
Br0thazS0ul
4
gunakan metode dari perpustakaan dukungan,TextViewCompat.setTextAppearance
Rubin Yoo
97

Anda bisa memberikan ContextThemeWrapper ke konstruktor seperti ini:

TextView myText = new TextView(new ContextThemeWrapper(MyActivity.this, R.style.my_style));
maxcanna
sumber
1
barang bagus! satu-satunya cara saya dapat mengatur gaya pemrograman sambil mendukung API 8.
tbraun
Untuk beberapa alasan, itu tidak mempengaruhi gaya tombol saya. Aku telah menetapkan gaya saya seperti: <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. Dan kemudian saya memanggil dengan konstruksi: new Button(new ContextThemeWrapper(context, R.style.TabButton));. Tapi tombol itu mengabaikan pengaturan saya. Apakah saya melakukan sesuatu yang salah di sini?
Aleks N.
@ AlaksiejN. Anda harus mewarisi dari Widget. Gaya tombol seperti iniparent="@android:style/Widget.Button"
maxcanna
@ Maxcanna Untuk beberapa alasan menambahkan parenttidak berubah sedikit pun. Jadi saya langsung saja inflatesolusinya.
Aleks N.
11
@ AliakseiN. Anda perlu menggunakan konstruktor 3-arg, mis new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). Jika tidak, gaya tombol default akan diterapkan, dan gaya ini akan menimpa gaya tombol yang telah Anda gabungkan ke dalam tema melalui ContextThemeWrapper.
Newtonx
17

Anda dapat mengatur gaya dalam konstruktor (tetapi gaya tidak dapat diubah / diset secara dinamis).

View(Context, AttributeSet, int)( intadalah atribut dalam tema saat ini yang berisi referensi ke gaya)

Jawaban dari Romain Guy

referensi

Dandre Allison
sumber
jawaban Anda menyesatkan - sudahkah Anda mencoba membaca utas ini sampai akhir?
andr
3
Bagaimana itu menyesatkan? Jawaban yang diterima menyesatkan, karena Romain Guy secara eksplisit mengatakan bahwa Anda dapat "mengatur" gaya pemrograman. Tidak ada fasilitas untuk mengubahnya secara dinamis. Utas ini tampaknya tidak berpikir bahwa itulah masalahnya.
Dandre Allison
1
Hati-hati, panggilan ini memerlukan API level 11.
Martin Capodici
1
@PaulVerest itu bukan kutipan.
Dandre Allison
6
Int terakhir bukan sumber daya gaya. Itu adalah "Atribut dalam tema saat ini yang berisi referensi ke sumber daya gaya yang memasok nilai default untuk tampilan."
rve
11

Parameter int defStyleAttrtidak menentukan gaya. Dari dokumentasi Android:

defStyleAttr - Atribut dalam tema saat ini yang berisi referensi ke sumber daya gaya yang memasok nilai default untuk tampilan. Bisa 0 hingga tidak mencari default.

Untuk mengatur gaya dalam View constructor kami memiliki 2 solusi yang mungkin:

  1. Dengan menggunakan ContextThemeWrapper:

    ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
    TextView textView = new TextView(wrappedContext, null, 0);
  2. Dengan konstruktor empat argumen (tersedia mulai dari LOLLIPOP):

    TextView textView = new TextView(yourContext, null, 0, R.style.your_style);

Hal utama untuk kedua solusi - defStyleAttrparameter harus 0 untuk menerapkan gaya kita ke tampilan.

DmitryArc
sumber
5

Mengubah gaya secara dinamis belum didukung (belum). Anda harus mengatur gaya sebelum tampilan dibuat, melalui XML.

Chris Cashwell
sumber
20
yang kebetulan merupakan hal yang sama, sebenarnya
njzk2
@ njzk2 terima kasih ... jelas tidak memikirkan komentarnya sebelum memposting. Tidak ada cara untuk mengatur gaya secara pemrograman sebelum UI dibuat, sehingga kode yang sama akan digunakan untuk mengubah atau mengatur gaya secara pemrograman.
Chris Cashwell
3

Jawaban yang diterima adalah solusi yang bagus untuk saya. Satu-satunya hal yang ditambahkan adalah tentang inflate()metode.

Dalam jawaban yang diterima semua android:layout_*parameter tidak akan diterapkan.

Alasannya adalah tidak ada cara untuk menyesuaikannya, sebab nulldisahkan sebagai ViewGroup parent.

Anda bisa menggunakannya seperti ini:

View view = inflater.inflate(R.layout.view, parent, false);

dan parentitu ViewGroup, dari mana Anda ingin menyesuaikan android:layout_*.

Dalam hal ini, semua properti relatif akan ditetapkan.

Semoga bermanfaat bagi seseorang.

Anor
sumber
2

Saat menggunakan tampilan khusus yang mungkin menggunakan pewarisan gaya (atau atribut gaya acara), Anda harus memodifikasi konstruktor kedua agar tidak kehilangan gaya. Ini berfungsi untuk saya, tanpa perlu menggunakan setTextAppearence () :

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, attrs.getStyleAttribute());
}
saiyancoder
sumber
2

Saya juga menemui masalah, dan saya menemukan cara untuk mengatur gaya secara pemrograman. Mungkin Anda semua membutuhkannya, Jadi saya perbarui di sana.

Param ketiga konstruktor View menerima jenis attr dalam tema Anda sebagai kode sumber di bawah ini:

public TextView(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.textViewStyle);
}

Jadi, Anda harus melewati jenis R.attr. ** daripada R.style. **

Dalam kode saya, saya melakukan langkah-langkah berikut:

Pertama, sesuaikan attr kustom untuk digunakan oleh tema di attr.xml.

<attr name="radio_button_style" format="reference" />

Kedua, spesifikkan gaya Anda di tema yang digunakan di style.xml.

 <style name="AppTheme" parent="android:Theme.Translucent">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    <item name="radio_button_style">@style/radioButtonStyle</item>
</style>
<style name="radioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">64dp</item>
    <item name="android:background">#000</item>
    <item name="android:button">@null</item>
    <item name="android:gravity">center</item>
    <item name="android:saveEnabled">false</item>
    <item name="android:textColor">@drawable/option_text_color</item>
    <item name="android:textSize">9sp</item>
</style>

Pada akhirnya, gunakan itu!

            RadioButton radioButton = new RadioButton(mContext, null, R.attr.radio_button_style);

tampilan yang dibuat secara terprogram akan menggunakan gaya yang ditentukan dalam tema Anda.

Anda dapat mencoba, dan berharap ini dapat bekerja untuk Anda dengan sempurna.

mrtwo
sumber
0

Saya hanya menguji dengan EditText tetapi Anda dapat menggunakan metode ini

public void setBackgroundResource (int resid)

untuk menerapkan gaya yang ditentukan dalam file XML.

Karena metode ini milik View, saya percaya ini akan bekerja dengan elemen UI apa pun.

salam.

floydaddict
sumber
Menurut dokumentasi, ini hanya bisa digunakan pada drawables, bukan dengan style. Jadi, jika ini benar-benar berfungsi, itu hanya "kebetulan" dan Anda tidak harus bergantung padanya.
Heinzi
0

Kita bisa menggunakan TextViewCompact.setTextAppearance(textView, R.style.xyz).

Android doc untuk referensi.

Kshitij Jain
sumber