Tema, gaya, dan lainnya


Hampir semua pengembang tahu bahwa ada Tema di android, tetapi penggunaannya biasanya terbatas pada menyalin xml dari Stack Overflow atau sumber daya lainnya. Ada informasi di Internet tentang topik, tetapi ini biasanya hanya resep untuk bagaimana mencapai hasil tertentu. Pada artikel ini, saya mencoba untuk memberikan gambaran pengantar tentang mekanisme stilisasi android.

Isi


Pendahuluan
Atribut untuk RectView
Gaya untuk RectView
Gaya bawaan
Atribut Tema Gaya RectView
Tema Tingkat Aktivitas
Lihat Topik
Cara menerapkan nilai atribut
Topik Sumberdaya
Ringkasan

Pendahuluan


Gaya dan Tema di android adalah mekanisme yang memungkinkan Anda memisahkan detail desain (misalnya, warna, ukuran font, dll.) Dari struktur UI. Untuk memahami cara kerjanya, contoh sederhana dengan tampilan ubahsuaian akan membantu kami.

Kita akan membutuhkan tampilan kustom sederhana yang akan menggambar persegi panjang dengan warna yang diinginkan dalam batas tampilan.

class RectView @JvmOverloads constructor( context: Context, attrSet: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrSet, defStyleAttr) { private val paint = Paint().apply { color = Color.BLUE } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } } 



Atribut untuk RectView


Sekarang saya ingin dapat mengubah warna persegi panjang tata letak.
Untuk melakukan ini, kita perlu menambahkan atribut baru, tambahkan attrs.xml ke file

 <resources> <attr name="rectColor" format="color"/> </resources> 

Sekarang dalam kode kita dapat mengakses id dari atribut ini melalui R.attr.rectColor dan
dalam tata letak layar, kita dapat menggunakan aplikasi: atribut rectColor.

 <org.berendeev.themes.RectView android:id="@+id/text2" android:layout_width="100dp" app:rectColor="@color/colorPrimary" android:layout_height="100dp"/> 

Tetapi RectView belum tahu bahwa ada atribut di mana Anda dapat mengambil warna untuk persegi panjang.

Mari kita ajarkan RectView untuk memahami atribut rectColor, menambahkan sekelompok atribut

 <resources> <attr name="rectColor" format="color"/> <declare-styleable name="RectView"> <attr name="rectColor"/> </declare-styleable> </resources> 

Di kelas R, 2 bidang baru dihasilkan:
R.styleable.RectView adalah array atribut id, saat ini merupakan array dari satu elemen R.attr.rectColor
R.styleable.RectView_rectColor adalah indeks id dari atribut dalam array R.styleable.RectView, yaitu atribut id yang bisa kita dapatkan dan R.styleable.RectView [R.styleable.RectView_rectColor]

Dan tambahkan dukungan untuk atribut rectColor ke kode.

 init { val typedArray = context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, 0 ) try { paint.color = typedArray.getColor( R.styleable.RectView_rectColor, Color.BLUE ) } finally { typedArray.recycle() } } 

Kode lengkap
 class RectView @JvmOverloads constructor( context: Context, attrSet: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrSet, defStyleAttr) { private val paint = Paint().apply { color = Color.BLUE } init { val typedArray = context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, 0 ) try { paint.color = typedArray.getColor( R.styleable.RectView_rectColor, Color.BLUE ) } finally { typedArray.recycle() } } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } } 


Sekarang kita bisa mengubah warna persegi panjang dari tata letak:



Gaya untuk RectView


Sekarang kita hanya memiliki satu atribut, tetapi anggaplah ada sepuluh di antaranya - akan sangat merepotkan bagi kita untuk mengatur semua atribut ini dalam tata letak untuk elemen yang sama setiap kali.

Keputusan untuk membuat segalanya dengan gaya.

 <style name="DefaultRectViewStyle"> <item name="rectColor">@color/colorAccent</item> </style> 

Sekarang kita dapat membuat segala jenis tampilan dengan tampilan yang sama dengan menentukan gaya.

 <org.berendeev.themes.RectView android:id="@+id/text2" android:layout_width="100dp" style="@style/DefaultRectViewStyle" android:layout_height="100dp"/> 

Gaya bawaan


Sekarang kami ingin semua tampilan memiliki semacam gaya secara default. Untuk melakukan ini, kita akan menentukan gaya default untuk metode memperolehStyledAttributes:

 context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, R.style.DefaultRectViewStyle ) 

Cukup. Sekarang semua RectView yang kita tambahkan ke tata letak akan memiliki gaya default DefaultRectViewStyle.

Atribut Tema Gaya RectView


Nilai standarnya bagus, tapi saya ingin mengontrol tata letak lebih fleksibel. Lebih mudah untuk mengatur gaya tampilan tertentu untuk seluruh aplikasi atau untuk Aktivitas terpisah.

Untuk ini kita perlu atribut baru. Kami akan mengatur nilainya dalam tema, nilainya akan menjadi gaya yang menentukan penampilan RectView.

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

Dan ajarkan rectView kami untuk memahami atribut tema ini. Dengan melewatkan parameter ketiga R.attr.rectViewStyle ke metode acceptStyledAttributes.

 context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, R.attr.rectViewStyle, R.style.DefaultRectViewStyle ) 

Sekarang, jika item dengan nama rectViewStyle dan nilai tipe gaya ditentukan dalam topik, gaya ini akan berlaku untuk semua RectView dengan tema ini.

Tema Tingkat Aktivitas


Kami menetapkan nilai atribut rectViewStyle dalam topik kami.

 <resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="rectViewStyle">@style/LocalRectViewStyle</item> </style> </resources> 

Tentukan topik dalam manifes aplikasi.

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.berendeev.themes"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest> 

Semua aktivitas akan diatur ke tema AppTheme default. Kami mengatur desain RectView untuk seluruh aplikasi.

Topik juga dapat diatur untuk Aktivitas tertentu dalam manifes.

 <activity android:name=".MainActivity" android:theme="@style/MyTheme"> 

Penting di sini bahwa tema yang akan kita atur di tingkat aplikasi atau aktivitas harus diwarisi dari tema standar. Misalnya, Theme.AppCompat. Kalau tidak, kita mengalami crash dalam runtime.
java.lang.IllegalStateException: Anda perlu menggunakan tema Theme.AppCompat (atau keturunan) dengan aktivitas ini.

Lihat Topik


Pada tingkat tampilan, kami tidak menginstal ulang tema, tetapi menimpa nilai atribut yang diperlukan, jadi kami tidak perlu mewarisi dari tema standar. Orang tua dapat kosong, atau misalnya, kita dapat mewarisi dari overlay ThemeOverlay.AppCompat.

Di sini kita mengatur tema MyOverlay untuk grup LinearLayout dan semua turunannya dalam hierarki.

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:theme="@style/MyOverlay"> <org.berendeev.themes.RectView android:layout_width="100dp" android:layout_height="100dp"/> </LinearLayout> 

Dalam subjek, kita bisa melakukannya tanpa orangtua, karena kami hanya memodifikasi tema aktivitas.

 <style name="MyOverlay"> <item name="rectViewStyle">@style/LocalRectViewStyle</item> </style> 

Cara menerapkan nilai atribut



Jika untuk tampilan kita mendefinisikan nilai atribut dalam tata letak dan gaya dan tema, maka urutan pemilihan nilai adalah sebagai berikut. Prioritas tertinggi adalah nilai yang ditentukan dalam tata letak, mis. jika nilai diatur dalam tata letak, maka gaya dan tema akan diabaikan, maka gaya akan berlanjut, maka tema dan di tempat terakhir gaya default.

Topik Sumberdaya


Nilai topik dapat digunakan dalam sumber daya. Misalnya, dalam drawable kita dapat mengatur warna yang akan tergantung pada warna yang diatur dalam tema.

 <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="?attr/colorPrimary"/> </shape> 

Sekarang warna persegi panjang tergantung pada nilai atribut colorPrimary dalam tema. Atribut dapat berupa apa saja. Sebagai contoh, kita dapat mengatur atribut kita di sumber daya dan mengatur nilainya dalam subjek.

Trik semacam itu dapat digunakan di semua sumber daya, misalnya, dalam pemilih atau dalam gambar vektor. Ini membuat desain lebih terstruktur dan fleksibel. Kami dapat dengan cepat mengubah tema untuk semua aktivitas.

Ringkasan


  • Tema dan gaya di tingkat sumber daya adalah satu dan sama, tetapi digunakan secara berbeda.
  • Tema dapat berisi tema lain, hanya makna atau gaya untuk tampilan.
  • Gaya ditunjukkan dalam tata letak di tingkat tampilan. LayoutInflater menghitung nilai gaya dan meneruskannya sebagai AttributeSet ke konstruktor View.
  • Tema adalah mekanisme yang memungkinkan Anda untuk menentukan tampilan secara global untuk seluruh aktivitas.
  • Nilai topik dapat diubah untuk elemen (dan keturunan) dalam hierarki tampilan.
  • Nilai tema dapat digunakan tidak hanya di View, tetapi juga di sumber daya.

PS: Jika artikel itu menarik, saya akan menulis artikel yang lebih maju atau artikel dengan banyak contoh nyata.

Source: https://habr.com/ru/post/id453812/


All Articles