Saat membuat tampilan khusus, saya perhatikan bahwa banyak orang tampaknya melakukannya seperti ini:
public MyView(Context context) {
super(context);
// this constructor used when programmatically creating view
doAdditionalConstructorWork();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// this constructor used when creating view through XML
doAdditionalConstructorWork();
}
private void doAdditionalConstructorWork() {
// init variables etc.
}
Pertanyaan pertama saya adalah, bagaimana dengan konstruktor MyView(Context context, AttributeSet attrs, int defStyle)
? Saya tidak yakin di mana itu digunakan, tetapi saya melihatnya di kelas super. Apakah saya membutuhkannya, dan di mana itu digunakan?
sumber
Jika Anda mengesampingkan ketiga konstruktor, mohon JANGAN
this(...)
PANGGILAN CASCADE . Anda seharusnya melakukan ini:Alasannya adalah bahwa kelas induk mungkin menyertakan atribut default di konstruktornya sendiri yang mungkin Anda sengaja timpa. Misalnya, ini adalah konstruktor untuk
TextView
:Jika Anda tidak menelepon
super(context)
, Anda tidak akan ditetapkan dengan benarR.attr.textViewStyle
sebagai style attr.sumber
MyView (Konteks konteks)
Digunakan ketika instanciating Views secara pemrograman.
MyView (Konteks konteks, attret Atribut)
Digunakan oleh
LayoutInflater
untuk menerapkan atribut xml. Jika salah satu dari atribut ini dinamaistyle
, atribut akan mencari gaya sebelum mencari nilai eksplisit dalam file tata letak xml.MyView (Konteks konteks, attrs AtributSet, int defStyleAttr)
Misalkan Anda ingin menerapkan gaya default ke semua widget tanpa harus menentukan
style
di setiap file tata letak. Sebagai contoh, buat semua kotak centang berwarna merah muda secara default. Anda dapat melakukan ini dengan defStyleAttr dan kerangka kerja akan mencari gaya default di tema Anda.Catatan yang
defStyleAttr
salah disebutkandefStyle
beberapa waktu lalu dan ada beberapa diskusi tentang apakah konstruktor ini benar-benar diperlukan atau tidak. Lihat https://code.google.com/p/android/issues/detail?id=12683MyView (Konteks konteks, attret AttributeSet, int defStyleAttr, int defStyleRes)
Konstruktor ke-3 berfungsi dengan baik jika Anda memiliki kontrol atas tema dasar aplikasi. Itu bekerja untuk google karena mereka mengirim widget mereka di samping Tema default. Tapi misalkan Anda sedang menulis perpustakaan widget dan Anda ingin mengatur gaya default tanpa pengguna Anda perlu mengubah tema mereka. Anda sekarang dapat melakukan ini
defStyleRes
dengan mengaturnya ke nilai default di 2 konstruktor pertama:Semua seutuhnya
Jika Anda menerapkan pandangan Anda sendiri, hanya 2 konstruktor pertama yang diperlukan dan dapat dipanggil oleh framework.
Jika Anda ingin Tampilan Anda dapat diperluas, Anda dapat menerapkan konstruktor ke-4 untuk anak-anak kelas Anda agar dapat menggunakan gaya global.
Saya tidak melihat kasus penggunaan nyata untuk konstruktor ke-3. Mungkin jalan pintas jika Anda tidak memberikan gaya default untuk widget Anda, tetapi tetap ingin pengguna Anda dapat melakukannya. Seharusnya tidak banyak terjadi.
sumber
Kotlin tampaknya menghilangkan banyak rasa sakit ini:
@JvmOverloads akan menghasilkan semua konstruktor yang diperlukan (lihat dokumentasi anotasi itu ), yang masing-masing mungkin memanggil super (). Kemudian, cukup ganti metode inisialisasi Anda dengan blok init {} Kotlin. Kode pelat boiler hilang!
sumber
Konstruktor ketiga jauh lebih rumit. Izinkan saya memberi contoh.
Paket dukungan-v7
SwitchCompact
mendukungthumbTint
dantrackTint
atribut sejak 24 versi sementara 23 versi tidak mendukung mereka. Sekarang Anda ingin mendukung mereka dalam versi 23 dan bagaimana Anda akan mencapai ini?Kita asumsikan menggunakan kustom View
SupportedSwitchCompact
meluasSwitchCompact
.Ini gaya kode tradisional. Perhatikan bahwa kita meneruskan 0 ke param ketiga di sini . Ketika Anda menjalankan kode, Anda akan menemukan
getThumbDrawable()
selalu mengembalikan null betapa anehnya karena metodegetThumbDrawable()
ini adalah metode kelas supernyaSwitchCompact
.Jika Anda lolos
R.attr.switchStyle
ke param ketiga, semuanya berjalan dengan baik. Jadi mengapa?Param ketiga adalah atribut sederhana. Atribut menunjuk ke sumber daya gaya. Dalam kasus di atas, sistem akan menemukan
switchStyle
atribut dalam tema saat ini untungnya sistem menemukannya.Di
frameworks/base/core/res/res/values/themes.xml
, Anda akan melihat:sumber
Jika Anda harus menyertakan tiga konstruktor seperti yang sedang dibahas sekarang, Anda dapat melakukannya juga.
sumber