Codelab ini adalah bagian dari kursus Dasar-Dasar Android Kotlin. Anda akan mendapatkan manfaat maksimal dari kursus ini jika menyelesaikan codelab secara berurutan. Semua codelab kursus tercantum di halaman landing codelab Dasar-Dasar Android Kotlin.
Pengantar
Dalam codelab sebelumnya di kursus ini, Anda menggunakan fungsi findViewById()
untuk mendapatkan referensi ke tampilan. Jika aplikasi Anda memiliki hierarki tampilan yang kompleks, findViewById()
akan mahal dan memperlambat aplikasi, karena Android melintasi hierarki tampilan, dimulai dari root, hingga menemukan tampilan yang diinginkan. Untungnya, ada cara yang lebih baik.
Untuk menyetel data dalam tampilan, Anda telah menggunakan resource string dan menyetel data dari aktivitas. Akan lebih efisien jika tampilan mengetahui data. Dan untungnya, hal ini dapat dilakukan.
Dalam codelab ini, Anda akan mempelajari cara menggunakan data binding untuk menghilangkan kebutuhan akan findViewById()
. Anda juga akan mempelajari cara menggunakan data binding untuk mengakses data langsung dari tampilan.
Yang harus sudah Anda ketahui
Anda harus memahami:
- Pengertian aktivitas, dan cara menyiapkan aktivitas dengan tata letak di
onCreate()
. - Membuat tampilan teks dan menyetel teks yang ditampilkan tampilan teks.
- Menggunakan
findViewById()
untuk mendapatkan referensi ke tampilan. - Membuat dan mengedit tata letak XML dasar untuk tampilan.
Yang akan Anda pelajari
- Cara menggunakan Library Data Binding untuk menghilangkan panggilan yang tidak efisien ke
findViewById()
. - Cara mengakses data aplikasi langsung dari XML.
Yang akan Anda lakukan
- Ubah aplikasi untuk menggunakan data binding, bukan
findViewById()
, dan untuk mengakses data langsung dari file XML tata letak.
Dalam codelab ini, Anda akan memulai dengan aplikasi AboutMe dan mengubah aplikasi untuk menggunakan data binding. Aplikasi akan terlihat persis sama setelah Anda selesai!
Berikut fungsi aplikasi AboutMe:
- Saat pengguna membuka aplikasi, aplikasi akan menampilkan nama, kolom untuk memasukkan nama panggilan, tombol Selesai, gambar bintang, dan teks yang dapat di-scroll.
- Pengguna dapat memasukkan nama panggilan dan mengetuk tombol Selesai. Kolom dan tombol yang dapat diedit diganti dengan tampilan teks yang menampilkan nama panggilan yang dimasukkan.
Anda dapat menggunakan kode yang Anda buat di codelab sebelumnya, atau Anda dapat mendownload kode AboutMeDataBinding-Starter dari GitHub.
Kode yang Anda tulis di codelab sebelumnya menggunakan fungsi findViewById()
untuk mendapatkan referensi ke tampilan.
Setiap kali Anda menggunakan findViewById()
untuk menelusuri tampilan setelah tampilan dibuat atau dibuat ulang, sistem Android akan menjelajahi hierarki tampilan saat runtime untuk menemukannya. Jika aplikasi Anda hanya memiliki beberapa tampilan, hal ini tidak menjadi masalah. Namun, aplikasi produksi mungkin memiliki puluhan tampilan dalam tata letak, dan meskipun dengan desain terbaik, akan ada tampilan bertingkat.
Bayangkan tata letak linear yang berisi scroll view yang berisi tampilan teks. Untuk hierarki tampilan yang besar atau dalam, menemukan tampilan dapat memakan waktu yang cukup lama sehingga dapat memperlambat aplikasi secara signifikan bagi pengguna. Menge-cache tampilan dalam variabel dapat membantu, tetapi Anda tetap harus menginisialisasi variabel untuk setiap tampilan, di setiap namespace. Dengan banyaknya tampilan dan beberapa aktivitas, hal ini juga akan menambah penggunaan data.
Salah satu solusinya adalah membuat objek yang berisi referensi ke setiap tampilan. Objek ini, yang disebut objek Binding
, dapat digunakan oleh seluruh aplikasi Anda. Teknik ini disebut data binding. Setelah objek pengikatan dibuat untuk aplikasi Anda, Anda dapat mengakses tampilan, dan data lainnya, melalui objek pengikatan, tanpa harus melintasi hierarki tampilan atau menelusuri data.
Data binding memiliki manfaat berikut:
- Kode lebih pendek, lebih mudah dibaca, dan lebih mudah dikelola daripada kode yang menggunakan
findByView()
. - Data dan tampilan dipisahkan dengan jelas. Manfaat data binding ini akan menjadi semakin penting di bagian selanjutnya dalam kursus ini.
- Sistem Android hanya melintasi hierarki tampilan satu kali untuk mendapatkan setiap tampilan, dan hal ini terjadi selama startup aplikasi, bukan saat runtime ketika pengguna berinteraksi dengan aplikasi.
- Anda mendapatkan keamanan jenis untuk mengakses tampilan. (Type safety berarti compiler memvalidasi jenis saat mengompilasi, dan akan menampilkan error jika Anda mencoba menetapkan jenis yang salah ke sebuah variabel.)
Dalam tugas ini, Anda akan menyiapkan data binding, dan menggunakan data binding untuk mengganti panggilan ke findViewById()
dengan panggilan ke objek binding.
Langkah 1: Aktifkan data binding
Untuk menggunakan data binding, Anda perlu mengaktifkan data binding di file Gradle, karena data binding tidak diaktifkan secara default. Hal ini karena data binding meningkatkan waktu kompilasi dan dapat memengaruhi waktu peluncuran aplikasi.
- Jika Anda tidak memiliki aplikasi AboutMe dari codelab sebelumnya, dapatkan kode AboutMeDataBinding-Starter dari GitHub. Buka di Android Studio.
- Buka file
build.gradle (Module: app)
. - Di dalam bagian
android
, sebelum kurung kurawal penutup, tambahkan bagiandataBinding
dan tetapkanenabled
ketrue
.
dataBinding {
enabled = true
}
- Saat diminta, Sinkronkan project. Jika Anda tidak diminta, pilih File > Sync Project with Gradle Files.
- Anda dapat menjalankan aplikasi, tetapi tidak akan melihat perubahan apa pun.
Langkah 2: Ubah file tata letak agar dapat digunakan dengan data binding
Untuk menggunakan binding data, Anda harus membungkus tata letak XML dengan tag <layout>
. Hal ini dilakukan agar class root tidak lagi menjadi grup tampilan, tetapi menjadi tata letak yang berisi grup tampilan dan tampilan. Objek binding kemudian dapat mengetahui tata letak dan tampilan di dalamnya.
- Buka file
activity_main.xml
. - Beralihlah ke tab Teks.
- Tambahkan
<layout></layout>
sebagai tag terluar di sekitar<LinearLayout>
.
<layout>
<LinearLayout ... >
...
</LinearLayout>
</layout>
- Pilih Code > Reformat code untuk memperbaiki indentasi kode.
Pernyataan namespace untuk tata letak harus berada di tag terluar.
- Potong deklarasi namespace dari
<LinearLayout>
dan tempelkan ke tag<layout>
. Tag<layout>
pembuka Anda akan terlihat seperti yang ditunjukkan di bawah, dan tag<LinearLayout>
hanya boleh berisi properti tampilan.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
- Bangun dan jalankan aplikasi Anda untuk memverifikasi bahwa Anda melakukannya dengan benar.
Langkah 3: Buat objek pengikatan di aktivitas utama
Tambahkan referensi ke objek binding ke aktivitas utama, sehingga Anda dapat menggunakannya untuk mengakses tampilan:
- Buka file
MainActivity.kt
. - Sebelum
onCreate()
, di level teratas, buat variabel untuk objek binding. Variabel ini biasanya disebutbinding
.
Jenisbinding
, classActivityMainBinding
, dibuat oleh compiler khusus untuk aktivitas utama ini. Nama ini berasal dari nama file tata letak, yaituactivity_main + Binding
.
private lateinit var binding: ActivityMainBinding
- Jika diminta oleh Android Studio, impor
ActivityMainBinding
. Jika Anda tidak diminta, klikActivityMainBinding
dan tekanAlt+Enter
(Option+Enter
di Mac) untuk mengimpor class yang tidak ada ini. (Untuk pintasan keyboard lainnya, lihat Pintasan keyboard.)
Pernyataanimport
akan terlihat mirip dengan yang ditampilkan di bawah.
import com.example.android.aboutme.databinding.ActivityMainBinding
Selanjutnya, Anda mengganti fungsi setContentView()
saat ini dengan petunjuk yang melakukan hal berikut:
- Membuat objek binding.
- Menggunakan fungsi
setContentView()
dari classDataBindingUtil
untuk mengaitkan tata letakactivity_main
denganMainActivity
. FungsisetContentView()
ini juga menangani beberapa penyiapan pengikatan data untuk tampilan.
- Di
onCreate()
, ganti panggilansetContentView()
dengan baris kode berikut.
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
- Impor
DataBindingUtil
.
import androidx.databinding.DataBindingUtil
Langkah 4: Gunakan objek binding untuk mengganti semua panggilan ke findViewById()
Sekarang Anda dapat mengganti semua panggilan ke findViewById()
dengan referensi ke tampilan yang ada di objek binding. Saat objek binding dibuat, compiler akan membuat nama tampilan di objek binding dari ID tampilan dalam tata letak, lalu mengonversinya menjadi camel case. Jadi, misalnya, done_button
adalah doneButton
dalam objek binding, nickname_edit
menjadi nicknameEdit
, dan nickname_text
menjadi nicknameText
.
- Di
onCreate()
, ganti kode yang menggunakanfindViewById()
untuk menemukandone_button
dengan kode yang mereferensikan tombol dalam objek binding.
Ganti kode ini:findViewById<Button>(R.id.
done_button
)
dengan:binding.doneButton
Kode yang sudah selesai untuk menyetel pemroses klik dionCreate()
akan terlihat seperti ini.
binding.doneButton.setOnClickListener {
addNickname(it)
}
- Lakukan hal yang sama untuk semua panggilan ke
findViewById()
dalam fungsiaddNickname()
.
Ganti semua kemunculanfindViewById<
View
>(R.id.
id_view
)
denganbinding.
idView
. Lakukan dengan cara berikut:
- Hapus definisi untuk variabel
editText
dannicknameTextView
beserta panggilannya kefindViewById()
. Hal ini akan menyebabkan error. - Perbaiki error dengan mendapatkan tampilan
nicknameText
,nicknameEdit
, dandoneButton
dari objekbinding
, bukan dari variabel (yang dihapus). - Ganti
view.visibility
denganbinding.doneButton.visibility
. Penggunaanbinding.doneButton
, bukanview
yang diteruskan, membuat kode lebih konsisten.
Hasilnya adalah kode berikut:
binding.nicknameText.text = binding.nicknameEdit.text
binding.nicknameEdit.visibility = View.GONE
binding.doneButton.visibility = View.GONE
binding.nicknameText.visibility = View.VISIBLE
- Tidak ada perubahan fungsi. Secara opsional, Anda sekarang dapat menghilangkan parameter
view
dan memperbarui semua penggunaanview
untuk menggunakanbinding.doneButton
di dalam fungsi ini.
nicknameText
memerlukanString
, dannicknameEdit.text
adalahEditable
. Saat menggunakan binding data, Anda harus mengonversiEditable
secara eksplisit keString
.
binding.nicknameText.text = binding.nicknameEdit.text.toString()
- Anda dapat menghapus impor yang berwarna abu-abu.
- Ubah fungsi menjadi Kotlin dengan menggunakan
apply{}
.
binding.apply {
nicknameText.text = nicknameEdit.text.toString()
nicknameEdit.visibility = View.GONE
doneButton.visibility = View.GONE
nicknameText.visibility = View.VISIBLE
}
- Buat dan jalankan aplikasi Anda...dan aplikasi akan terlihat dan berfungsi persis sama seperti sebelumnya.
Anda dapat memanfaatkan data binding untuk membuat class data tersedia langsung untuk tampilan. Teknik ini menyederhanakan kode, dan sangat berguna untuk menangani kasus yang lebih rumit.
Untuk contoh ini, alih-alih menyetel nama dan nama panggilan menggunakan resource string, Anda membuat class data untuk nama dan nama panggilan. Anda membuat class data tersedia untuk tampilan menggunakan data binding.
Langkah 1: Buat class data MyName
- Di Android Studio di direktori
java
, buka fileMyName.kt
. Jika Anda tidak memiliki file ini, buat file Kotlin baru dan beri namaMyName.kt
. - Tentukan class data untuk nama dan nama panggilan. Gunakan string kosong sebagai nilai default.
data class MyName(var name: String = "", var nickname: String = "")
Langkah 2: Tambahkan data ke tata letak
Dalam file activity_main.xml
, nama saat ini ditetapkan dalam TextView
dari resource string. Anda perlu mengganti referensi ke nama dengan referensi ke data di class data.
- Buka
activity_main.xml
di tab Text. - Di bagian atas tata letak, antara tag
<layout>
dan<LinearLayout>
, sisipkan tag<data></data>
. Di sinilah Anda akan menghubungkan tampilan dengan data.
<data>
</data>
Di dalam tag data, Anda dapat mendeklarasikan variabel bernama yang menyimpan referensi ke class.
- Di dalam tag
<data>
, tambahkan tag<variable>
. - Tambahkan parameter
name
untuk memberi variabel nama"myName"
. Tambahkan parametertype
dan tetapkan jenisnya ke nama yang sepenuhnya memenuhi syarat dari class dataMyName
(nama paket + nama variabel).
<variable
name="myName"
type="com.example.android.aboutme.MyName" />
Sekarang, alih-alih menggunakan resource string untuk nama, Anda dapat mereferensikan variabel myName
.
- Ganti
android:text="@string/name"
dengan kode di bawah.
@={}
adalah direktif untuk mendapatkan data yang direferensikan di dalam tanda kurung kurawal.
myName
mereferensikan variabel myName
yang sebelumnya Anda tentukan, yang mengarah ke class data myName
dan mengambil properti name
dari class.
android:text="@={myName.name}"
Langkah 3: Buat data
Sekarang Anda memiliki referensi ke data dalam file tata letak. Selanjutnya, Anda membuat data sebenarnya.
- Buka file
MainActivity.kt
. - Di atas
onCreate()
, buat variabel pribadi, yang juga disebutmyName
berdasarkan konvensi. Tetapkan instance class dataMyName
ke variabel, dengan meneruskan nama.
private val myName: MyName = MyName("Aleks Haecky")
- Di
onCreate()
, tetapkan nilai variabelmyName
dalam file tata letak ke nilai variabelmyName
yang baru saja Anda deklarasikan. Anda tidak dapat mengakses variabel di XML secara langsung. Anda harus mengaksesnya melalui objek pengikatan.
binding.myName = myName
- Hal ini dapat menampilkan error, karena Anda perlu memuat ulang objek binding setelah melakukan perubahan. Bangun aplikasi Anda, dan error akan hilang.
Langkah 4: Gunakan class data untuk nama panggilan di TextView
Langkah terakhir adalah menggunakan class data untuk nama panggilan di TextView
.
- Buka
activity_main.xml
. - Di tampilan teks
nickname_text
, tambahkan propertitext
. Referensinickname
di class data, seperti yang ditunjukkan di bawah.
android:text="@={myName.nickname}"
- Di
ActivityMain
, gantinicknameText.text = nicknameEdit.text.toString()
dengan kode untuk menetapkan nama panggilan di variabelmyName
.
myName?.nickname = nicknameEdit.text.toString()
Setelah nama panggilan ditetapkan, Anda ingin kode Anda memuat ulang UI dengan data baru. Untuk melakukannya, Anda harus membatalkan semua ekspresi pengikatan sehingga dibuat ulang dengan data yang benar.
- Tambahkan
invalidateAll()
setelah menyetel nama panggilan agar UI dimuat ulang dengan nilai dalam objek binding yang diperbarui.
binding.apply {
myName?.nickname = nicknameEdit.text.toString()
invalidateAll()
...
}
- Bangun dan jalankan aplikasi Anda, dan aplikasi akan berfungsi persis sama seperti sebelumnya.
Project Android Studio: AboutMeDataBinding
Langkah-langkah menggunakan data binding untuk mengganti panggilan ke findViewById()
:
- Aktifkan data binding di bagian android pada file
build.gradle
:dataBinding { enabled = true }
- Gunakan
<layout>
sebagai tampilan root dalam tata letak XML Anda. - Tentukan variabel binding:
private lateinit var binding: ActivityMainBinding
- Buat objek binding di
MainActivity
, menggantikansetContentView
:binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
- Ganti panggilan ke
findViewById()
dengan referensi ke tampilan di objek binding. Misalnya: TombolfindViewById<Button>(R.id.done_button) ⇒ binding.doneBu
(Dalam contoh, nama tampilan dibuat camel case dariid
tampilan di XML.)
Langkah-langkah untuk mengikat tampilan ke data:
- Buat class data untuk data Anda.
- Tambahkan blok
<data>
di dalam tag<layout>
. - Tentukan
<variable>
dengan nama, dan jenis yang merupakan class data.
<data>
<variable
name="myName"
type="com.example.android.aboutme.MyName" />
</data>
- Di
MainActivity
, buat variabel dengan instance class data. Contoh:private val myName: MyName = MyName("Aleks Haecky")
- Di objek binding, tetapkan variabel ke variabel yang baru saja Anda buat:
binding.myName = myName
- Dalam XML, tetapkan konten tampilan ke variabel yang Anda tentukan di blok
<data>
. Gunakan notasi titik untuk mengakses data di dalam class data.android:text="@={myName.name}"
Kursus Udacity:
Dokumentasi developer Android:
- Library Data Binding
- Class binding yang dihasilkan
- Mulai menggunakan pengikatan data
- Tata letak dan ekspresi binding
Bagian ini mencantumkan kemungkinan tugas pekerjaan rumah untuk siswa yang mengerjakan codelab ini sebagai bagian dari kursus yang dipimpin oleh instruktur. Instruktur menentukan hal berikut:
- Memberikan pekerjaan rumah jika diperlukan.
- Memberi tahu siswa cara mengirimkan tugas pekerjaan rumah.
- Memberi nilai tugas pekerjaan rumah.
Instruktur bisa menggunakan saran ini sesuai kebutuhan, dan bebas menugaskan pekerjaan rumah lain yang dirasa cocok.
Jika Anda menyelesaikan codelab ini sendiri, gunakan tugas pekerjaan rumah ini untuk menguji pengetahuan Anda.
Jawab pertanyaan-pertanyaan berikut
Pertanyaan 1
Mengapa Anda ingin meminimalkan panggilan eksplisit dan implisit ke findViewById()
?
- Setiap kali dipanggil,
findViewById()
akan melintasi hierarki tampilan. findViewById()
berjalan di thread utama atau UI thread.- Panggilan ini dapat memperlambat antarmuka pengguna.
- Aplikasi Anda kemungkinan tidak mengalami error.
Pertanyaan 2
Bagaimana Anda mendeskripsikan pengikatan data?
Misalnya, berikut beberapa hal yang dapat Anda katakan tentang binding data:
- Ide besar tentang pengikatan data adalah membuat objek yang menghubungkan/memetakan/mengikat dua informasi yang berjauhan bersama-sama pada waktu kompilasi, sehingga Anda tidak perlu mencari data pada waktu runtime.
- Objek yang menampilkan binding ini kepada Anda disebut objek binding.
- Objek binding dibuat oleh compiler.
Pertanyaan 3
Manakah dari berikut ini yang BUKAN merupakan manfaat pengikatan data?
- Kode lebih pendek, lebih mudah dibaca, dan lebih mudah dikelola.
- Data dan tampilan dipisahkan dengan jelas.
- Sistem Android hanya melintasi hierarki tampilan satu kali untuk mendapatkan setiap tampilan.
- Memanggil
findViewById()
akan menghasilkan error compiler. - Keamanan jenis untuk mengakses tampilan.
Pertanyaan 4
Apa fungsi tag <layout>
?
- Anda membungkusnya di sekitar tampilan root dalam tata letak.
- Binding dibuat untuk semua tampilan dalam tata letak.
- Menetapkan tampilan tingkat teratas dalam tata letak XML yang menggunakan data binding.
- Anda dapat menggunakan tag
<data>
di dalam<layout>
untuk mengikat variabel ke class data.
Pertanyaan 5
Manakah cara yang benar untuk mereferensikan data terikat dalam tata letak XML?
android:text="@={myDataClass.property}"
android:text="@={myDataClass}"
android:text="@={myDataClass.property.toString()}"
android:text="@={myDataClass.bound_data.property}"
Mulai pelajaran berikutnya:
Untuk link ke codelab lain dalam kursus ini, lihat halaman landing codelab Dasar-Dasar Android Kotlin.