Android menawarkan model canggih dan kuat yang terdiri dari berbagai komponen untuk membangun UI Anda, berdasarkan
class tata letak dasar
View
dan
ViewGroup
. Platform ini berisi
berbagai subclass View
dan ViewGroup
bawaan—yang disebut widget dan
yang sesuai—yang dapat Anda gunakan untuk membuat UI.
Daftar sebagian widget yang tersedia mencakup Button
,
TextView
,
EditText
,
ListView
,
CheckBox
,
RadioButton
,
Gallery
,
Spinner
, dan yang memiliki kegunaan khusus
AutoCompleteTextView
,
ImageSwitcher
, dan
TextSwitcher
.
Tata letak yang tersedia antara lain
LinearLayout
,
FrameLayout
,
RelativeLayout
,
dan lainnya. Untuk contoh lainnya, lihat
Tata letak umum.
Jika tidak ada widget atau tata letak bawaan yang memenuhi kebutuhan, Anda dapat membuatnya sendiri
Subclass View
. Jika Anda hanya perlu membuat penyesuaian
kecil pada {i>widget<i} yang ada atau
, Anda dapat membuat subclass widget atau tata letak dan mengganti metodenya.
Membuat subclass View
sendiri memberi Anda kontrol yang akurat atas tampilan dan
fungsi dari elemen layar. Untuk memberikan gambaran tentang kontrol yang Anda dapatkan dengan tampilan kustom, berikut adalah
beberapa contoh hal yang dapat Anda lakukan dengan kebijakan tersebut:
-
Anda dapat membuat jenis
View
yang sepenuhnya dirender secara khusus—misalnya, "volume kontrol" {i>knob<i}, yang dirender menggunakan grafik 2D, yang menyerupai kontrol elektronik analog. -
Anda dapat menggabungkan grup komponen
View
ke dalam satu komponen baru, mungkin untuk membuat sesuatu seperti kotak kombo (kombinasi daftar {i>pop-up<i} dan {i>free entri text field<i}), sebuah kontrol pemilih panel ganda (panel kiri dan kanan berisi daftar di masing-masing tempat Anda dapat menetapkan ulang item mana yang ada di daftar mana), dan seterusnya. -
Anda dapat mengganti cara komponen
EditText
dirender di layar. Tujuan Aplikasi contoh NotePad menggunakan efek ini dengan baik untuk membuat halaman notepad bergaris. - Anda dapat mencatat peristiwa lain—seperti penekanan tombol—dan menanganinya dengan cara kustom, seperti seperti untuk game.
Bagian berikut menjelaskan cara membuat tampilan kustom dan menggunakannya di aplikasi Anda. Sebagai
informasi referensi yang mendetail, lihat
Class View
.
Pendekatan dasar
Berikut ringkasan umum tentang hal-hal yang perlu diketahui untuk membuat View
Anda sendiri
komponen:
-
Perluas class atau subclass
View
yang ada dengan class Anda sendiri. -
Ganti beberapa metode dari superclass. Metode superclass yang perlu diganti dimulai dengan
on
—misalnya,onDraw()
,onMeasure()
, danonKeyDown()
. Ini mirip dengan peristiwaon
diActivity
atauListActivity
yang Anda untuk siklus proses dan hook fungsi lainnya. - Gunakan class ekstensi baru. Setelah selesai, Anda dapat menggunakan class ekstensi baru sebagai pengganti tampilan yang menjadi dasarnya.
Komponen yang disesuaikan sepenuhnya
Anda dapat membuat komponen grafis yang sepenuhnya disesuaikan yang muncul dengan cara apa pun kita inginkan. Mungkin Anda menginginkan pengukur VU grafis yang terlihat seperti pengukur analog lama, atau tampilan teks untuk bernyanyi bersama bola yang memantul bergerak di sepanjang kata saat Anda bernyanyi bersama mesin karaoke. Mungkin Anda ingin sesuatu yang tidak dapat dilakukan oleh komponen {i>built-in<i}, tidak peduli bagaimana Anda menggabungkannya.
Untungnya, Anda dapat membuat komponen yang terlihat dan berperilaku sesuai keinginan, hanya terbatas berdasarkan imajinasi Anda, ukuran layar, dan daya pemrosesan yang tersedia, ingatlah bahwa aplikasi mungkin harus berjalan pada perangkat dengan daya yang jauh lebih kecil daripada {i>desktop<i} Anda Infrastruktur Cloud.
Untuk membuat komponen yang disesuaikan sepenuhnya, pertimbangkan hal berikut:
-
Tampilan paling umum yang dapat diperluas adalah
View
, sehingga Anda biasanya memulai dengan memperluas ini untuk membuat komponen super baru. - Anda bisa menyediakan konstruktor, yang bisa mengambil atribut dan parameter dari XML, dan Anda bisa menggunakan atribut dan parameter Anda sendiri, seperti warna dan rentang VU meter atau lebar dan redaman jarum.
- Anda mungkin ingin membuat pemroses peristiwa, pengakses properti, dan pengubah sendiri serta yang lebih canggih di class komponen Anda.
-
Anda hampir pasti ingin mengganti
onMeasure()
dan juga mungkin perlu gantionDraw()
jika Anda ingin komponen menampilkan sesuatu. Meskipun keduanya memiliki perilaku default,onDraw()
default tidak melakukan apa pun, danonMeasure()
selalu menetapkan ukuran 100x100, yang mungkin tidak Anda inginkan. -
Anda juga dapat mengganti metode
on
lainnya, sesuai kebutuhan.
Memperluas onDraw() dan onMeasure()
Metode onDraw()
memberikan
Canvas
, yang dapat Anda
mengimplementasikan apa pun yang Anda inginkan: grafis 2D, komponen standar atau kustom lainnya, teks bergaya, atau
hal lain yang bisa Anda pikirkan.
onMeasure()
sedikit lebih terlibat. onMeasure()
adalah bagian penting
dari kontrak rendering antara
komponen Anda dan kontainernya. onMeasure()
harus
diabaikan untuk melaporkan pengukuran
bagian-bagian yang ada di dalamnya secara efisien dan akurat. Ini adalah
dibuat sedikit lebih kompleks dengan persyaratan batas dari induk—yang diteruskan ke
onMeasure()
—dan dengan persyaratan untuk memanggil
Metode setMeasuredDimension()
dengan lebar dan tinggi yang diukur setelah
yang dihitung. Jika Anda tidak memanggil metode ini dari metode onMeasure()
yang diganti,
menghasilkan pengecualian pada waktu pengukuran.
Pada level yang tinggi, penerapan onMeasure()
akan terlihat seperti ini:
-
Metode
onMeasure()
yang diganti dipanggil dengan lebar dan tinggi spesifikasi, yang diperlakukan sebagai persyaratan untuk pembatasan lebar dan tinggi pengukuran yang Anda hasilkan.widthMeasureSpec
danheightMeasureSpec
keduanya adalah kode bilangan bulat yang mewakili dimensi. Referensi lengkap tentang jenis batasan yang mungkin dibutuhkan oleh spesifikasi ini, bisa ditemukan di dokumentasi referensi padaView.onMeasure(int, int)
Dokumentasi referensi ini juga menjelaskan keseluruhan operasi pengukuran. -
Metode
onMeasure()
komponen Anda menghitung lebar dan tinggi pengukuran, yang diperlukan untuk merender komponen. URL harus tetap berada dalam spesifikasi yang diteruskan walaupun bisa melebihi mereka. Dalam hal ini, orang tua dapat memilih tindakan yang akan dilakukan, termasuk memotong, men-scroll, menampilkan pengecualian, atau memintaonMeasure()
mencoba lagi, mungkin dengan spesifikasi pengukuran yang berbeda. -
Saat lebar dan tinggi dihitung, panggil metode
setMeasuredDimension(int width, int height)
dengan metode pengukuran. Kegagalan dalam melakukan langkah ini akan menghasilkan pengecualian.
Berikut ringkasan metode standar lainnya yang dipanggil framework pada tampilan:
Kategori | Metode | Deskripsi |
---|---|---|
Kreasi | Konstruktor | Ada bentuk konstruktor yang dipanggil bila tampilan dibuat dari kode dan formulir yang dipanggil saat tampilan di-inflate dari file tata letak. Bentuk kedua mengurai dan menerapkan atribut yang ditentukan dalam file tata letak. |
|
Dipanggil setelah tampilan dan semua turunannya di-inflate dari XML. | |
Tata Letak |
|
Dipanggil guna menentukan persyaratan ukuran untuk tampilan ini dan semua turunannya. |
|
Dipanggil saat tampilan ini harus menetapkan ukuran dan posisi ke semua turunannya. | |
|
Dipanggil saat ukuran tampilan ini diubah. | |
Gambar |
|
Dipanggil saat tampilan harus merender kontennya. |
Pemrosesan peristiwa |
|
Dipanggil saat peristiwa tombol turun terjadi. |
|
Dipanggil saat peristiwa tombol ke atas terjadi. | |
|
Dipanggil saat peristiwa gerakan trackball terjadi. | |
|
Dipanggil saat peristiwa gerakan layar sentuh terjadi. | |
Fokus |
|
Dipanggil saat tampilan mendapatkan atau kehilangan fokus. |
|
Dipanggil saat jendela yang berisi tampilan mendapatkan atau kehilangan fokus. | |
Pemasangan |
|
Dipanggil saat tampilan dilampirkan ke jendela. |
|
Dipanggil saat tampilan dilepas dari jendelanya. | |
|
Dipanggil saat visibilitas jendela yang berisi tampilan diubah. |
Kontrol gabungan
Jika Anda tidak ingin membuat komponen yang
sepenuhnya disesuaikan tetapi ingin meletakkan
komponen yang dapat digunakan kembali yang terdiri dari grup kontrol yang ada, lalu membuat komponen
komponen (atau kontrol gabungan) mungkin lebih baik. Singkatnya, hal ini menyatukan beberapa
kontrol atau tampilan atomik menjadi sekelompok item logis yang dapat diperlakukan sebagai satu hal.
Misalnya, kotak kombo dapat berupa kombinasi dari kolom EditText
baris tunggal
dan tombol yang berdekatan dengan
daftar {i>pop-up<i} terlampir. Jika pengguna mengetuk tombol
dan memilih sesuatu dari
daftar, kolom EditText
akan diisi, tetapi pengguna juga dapat mengetik sesuatu
langsung ke EditText
jika diinginkan.
Di Android, ada dua tampilan lain yang tersedia untuk melakukan ini: Spinner
dan
AutoCompleteTextView
. Terlepas dari itu, konsep untuk kotak kombo ini adalah contoh yang baik.
Untuk membuat komponen gabungan, lakukan hal berikut:
-
Sama seperti dengan
Activity
, gunakan pendekatan deklaratif (berbasis XML) untuk membuat komponen yang ditampung atau menyusunnya menjadi bertingkat secara terprogram dari kode Anda. Tujuan titik awal yang biasa adalahLayout
, jadi buat class yang memperluasLayout
. Dalam kasus kotak kombo, Anda dapat menggunakanLinearLayout
dengan orientasi horizontal. Anda dapat menyusun bertingkat tata letak lain di dalamnya, sehingga komponen gabungan dapat kompleks dan terstruktur secara bebas. -
Dalam konstruktor untuk class baru, ambil parameter apa pun yang diharapkan oleh superclass dan teruskan
mereka melalui konstruktor superclass terlebih dahulu. Kemudian, Anda dapat menyiapkan tampilan
lain untuk digunakan
dalam komponen baru. Di sinilah Anda membuat kolom
EditText
dan daftar pop-up. Anda dapat memperkenalkan atribut dan parameter sendiri ke dalam XML yang yang dapat ditarik dan digunakan. -
Secara opsional, buat pemroses untuk peristiwa yang mungkin dihasilkan oleh tampilan yang dimuat Anda. Contohnya adalah
untuk pemroses klik item daftar guna memperbarui konten
EditText
jika pilihan daftar dibuat. -
Secara opsional, buat properti Anda sendiri dengan pengakses dan pengubah. Misalnya, biarkan
Nilai
EditText
ditetapkan di awal dalam komponen dan mengkueri kontennya saat diperlukan. -
Atau, ganti
onDraw()
danonMeasure()
. Ini biasanya tidak diperlukan ketika memperluasLayout
, karena tata letak memiliki perilaku default yang mungkin berfungsi dengan baik. -
Atau, ganti metode
on
lain, sepertionKeyDown()
, misalnya untuk memilih nilai {i>default<i} dari daftar {i>popup<i} kotak kombo ketika tombol tertentu diketuk.
Ada beberapa keuntungan dalam menggunakan Layout
sebagai dasar untuk kontrol kustom,
termasuk yang berikut:
- Anda bisa menetapkan tata letak menggunakan file XML deklaratif, sama seperti layar aktivitas, atau Anda bisa membuat tampilan secara terprogram dan memasukkannya ke dalam tata letak dari kode Anda.
-
Metode
onDraw()
danonMeasure()
, serta sebagian besar metode lainnya Metodeon
memiliki perilaku yang sesuai, sehingga Anda tidak perlu menggantinya. - Anda dapat dengan cepat membuat tampilan gabungan yang kompleks secara bebas dan menggunakannya kembali seolah-olah komponen tunggal.
Mengubah jenis tampilan yang ada
Jika ada komponen yang mirip dengan yang Anda inginkan, Anda dapat memperluas komponen tersebut dan mengganti
perilaku yang ingin
Anda ubah. Anda dapat melakukan semua hal dengan antarmuka yang disesuaikan
Namun, dengan memulai dari class yang lebih khusus dalam hierarki View
, Anda dapat
mendapatkan beberapa perilaku yang
melakukan apa yang Anda inginkan secara gratis.
Misalnya,
NotePad
aplikasi contoh menunjukkan banyak aspek dalam menggunakan platform Android. Di antaranya adalah memperluas
Tampilan EditText
untuk membuat notepad bergaris. Ini bukan contoh yang sempurna, dan API untuk
melakukan ini mungkin mengubah, tetapi hal itu
menunjukkan prinsip-prinsipnya.
Jika Anda belum melakukannya, impor contoh NotePad ke Android Studio atau lihat
sumber menggunakan tautan yang disediakan. Secara khusus, lihat definisi LinedEditText
di
NoteEditor.java
.
Berikut beberapa hal yang perlu diketahui dalam file ini:
-
Definisi
Class ditentukan dengan baris berikut:
public static class LinedEditText extends EditText
LinedEditText
didefinisikan sebagai class dalam dalamNoteEditor
aktivitas, tetapi bersifat publik sehingga dapat diakses sebagaiNoteEditor.LinedEditText
dari luar classNoteEditor
.Selain itu,
LinedEditText
adalahstatic
, yang berarti kode tersebut tidak menghasilkan yang disebut “metode sintetik{i>”<i} yang memungkinkannya mengakses data dari class induk. Ini berarti berperilaku sebagai class terpisah, bukan sesuatu yang sangat terkait denganNoteEditor
. Ini adalah cara yang lebih bersih untuk membuat class dalam jika class tersebut tidak memerlukan akses ke status dari kelas luar. Class ini membuat class yang dihasilkan tetap kecil dan dapat digunakan dengan mudah dari Google Cloud Platform.LinedEditText
memperluasEditText
, yang merupakan tampilan yang akan disesuaikan dalam kasus ini. Setelah Anda selesai, class baru dapat menggantikanEditText
yang normal {i>view<i}. -
Inisialisasi class
Seperti biasa, super dipanggil terlebih dahulu. Ini bukan konstruktor default, tetapi merupakan diparameterisasi.
EditText
dibuat dengan parameter ini saat di-inflate dari file tata letak XML. Jadi, konstruktor perlu mengambilnya dan meneruskannya ke konstruktor superclass. -
Metode yang diganti
Contoh ini hanya mengganti metode
onDraw()
, tetapi Anda mungkin perlu mengganti lainnya saat Anda membuat komponen kustom Anda sendiri.Untuk contoh ini, mengganti metode
onDraw()
memungkinkan Anda melukis garis biru di kanvas tampilanEditText
. Kanvas diteruskan ke ruang MetodeonDraw()
. Metodesuper.onDraw()
dipanggil sebelum metode tersebut berakhir. Metode superclass harus dipanggil. Dalam hal ini, panggil di akhir setelah Anda melukis garis-garis yang ingin Anda sertakan. -
Komponen kustom
Anda sekarang memiliki komponen kustom, tetapi bagaimana cara menggunakannya? Dalam contoh NotePad, kustom digunakan langsung dari tata letak deklaratif, jadi lihat
note_editor.xml
dalamres/layout
folder:<view xmlns:android="http://schemas.android.com/apk/res/android" class="com.example.android.notepad.NoteEditor$LinedEditText" android:id="@+id/note" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:padding="5dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:gravity="top" android:textSize="22sp" android:capitalize="sentences" />
Komponen kustom dibuat sebagai tampilan generik di XML, dan class ditetapkan menggunakan paket lengkap. Kelas dalam yang Anda tentukan direferensikan menggunakan Notasi
NoteEditor$LinedEditText
, yang merupakan cara standar untuk merujuk ke bagian dalam dalam bahasa pemrograman Java.Jika komponen tampilan kustom tidak didefinisikan sebagai class dalam, Anda dapat mendeklarasikan tampilan komponen dengan nama elemen XML dan mengecualikan atribut
class
. Contoh:<com.example.android.notepad.LinedEditText id="@+id/note" ... />
Perlu diketahui bahwa class
LinedEditText
kini merupakan file class terpisah. Jika berada di classNoteEditor
, teknik ini tidak akan berfungsi.Atribut dan parameter lain dalam definisi adalah atribut dan parameter yang diteruskan ke konstruktor komponen lalu diteruskan ke konstruktor
EditText
, sehingga parameter tersebut sama dengan yang Anda gunakan untuk tampilanEditText
. Kita bisa menambahkan parameter Anda sendiri.
Membuat komponen kustom hanya serumit yang Anda perlukan.
Komponen yang lebih canggih dapat menggantikan lebih banyak metode on
dan memperkenalkan
metode helpernya sendiri, yang secara substansial menyesuaikan properti dan perilakunya. Satu-satunya batasan adalah
imajinasi dan apa yang Anda
perlukan komponennya untuk melakukannya.