1. Sebelum memulai
Codelab ini memandu Anda menjalani proses membuat widget aplikasi untuk SociaLite. Pertama, Anda akan membuat widget Glance sederhana, dan menambahkannya ke SociaLite dan layar utama. Selanjutnya, Anda akan menambahkan status kosong ke widget menggunakan komponen dan tema Glance. Lalu, codelab ini akan memandu Anda dalam mendukung interaksi pengguna untuk memilih kontak favorit dari widget Anda. Terakhir, Anda akan mempelajari cara memperbarui widget dari aplikasi Anda.
Prasyarat
- Pengetahuan Kotlin dasar.
- Penyelesaian codelab Menyiapkan Android Studio, atau memahami cara menggunakan Android Studio dan menguji aplikasi di emulator Android 15 atau di perangkat fisik yang menjalankan Android 15.
- Pengetahuan Hilt dasar.
- Pengetahuan Compose dasar. Glance tidak menggunakan composable dari Jetpack Compose, tetapi Glance menggunakan kembali framework dan gaya coding-nya.
Yang akan Anda pelajari dalam codelab ini
- Cara mengonfigurasi aplikasi Anda untuk mendukung widget.
- Cara menggunakan komponen Glance untuk membuat tata letak responsif.
- Cara menggunakan
GlanceTheme
untuk mendukung warna dinamis pada layar utama pengguna. - Cara menangani interaksi pengguna di widget.
- Cara memperbarui widget dari aplikasi.
Yang Anda butuhkan
- Versi terbaru Android Studio.
- Perangkat pengujian atau emulator yang menjalankan Android 12 atau yang lebih baru.
- SDK Android 12 atau yang lebih baru.
2. Memulai persiapan
Mendapatkan kode awal
- Jika Anda telah menyelesaikan codelab Menangani penerapan layar penuh di Android 15 atau Menambahkan animasi fitur Kembali prediktif, lanjutkan ke bagian Menambahkan Widget karena Anda sudah memiliki kode awalnya.
- Download kode awal dari GitHub.
Atau, Anda dapat membuat clone repositori dan melihat branch codelab_improve_android_experience_2024.
git clone git@github.com:android/socialite.git
cd socialite
git checkout codelab_improve_android_experience_2024
- Buka SociaLite di Android Studio, lalu jalankan aplikasi di perangkat atau emulator Android 15 Anda. Anda akan melihat layar yang terlihat seperti berikut:
SociaLite dengan navigasi gestur
3. Menambahkan widget
Apa itu widget?
Widget adalah bagian dari aplikasi Anda yang dapat disematkan di dalam aplikasi Android lainnya. Biasanya, aplikasi disematkan di layar utama pengguna.
Menambahkan widget ke aplikasi Anda dapat memberi pengguna kemampuan untuk memulai tugas umum dengan cepat, melihat informasi sekilas, dan menyesuaikan perangkat mereka dengan konten Anda.
Apa itu Glance?
Jetpack Glance adalah library untuk menulis widget menggunakan API seperti Compose di Kotlin. Glance memiliki beberapa keunggulan yang sama dengan Compose, seperti rekomposisi, kode UI deklaratif yang ditulis dalam Kotlin, dan komponen yang beropini. Glance menghilangkan sebagian besar kebutuhan akan tampilan jarak jauh XML di widget Anda.
Membuat widget
Widget di Android dideklarasikan di AndroidManifest
sebagai elemen<receiver>
. Penerima ini harus diekspor, tangani android.appwidget.action.APPWIDGET_UPDATE
tindakan intent, dan sediakan file pengaturan widget aplikasi melalui elemen metadata bernama android.appwidget.provider
.
Menambahkan widget ke SociaLite
Anda ingin menambahkan widget ke Socialite yang memungkinkan pengguna melihat kontak favorit mereka dan apakah mereka memiliki pesan yang belum dibaca dari orang tersebut. Jika ya, mengetuk widget akan membawa pengguna ke chat kontak favoritnya. Selain itu, Anda menggunakan komponen dan penerapan tema Glance untuk memastikan widget terlihat baik dengan menggunakan desain responsif dan warna dinamis.
Untuk memulai, tambahkan widget "Halo Dunia" ke Socialite. Setelah itu, perluas kemampuan widget Anda.
Untuk melakukannya, lakukan hal berikut:
- Tambahkan dependensi Glance ke aplikasi Anda.
- Buat implementasi
GlanceAppWidget
. - Buat
GlanceAppWidgetReceiver
. - Konfigurasi widget Anda dengan file XML info widget aplikasi.
- Tambahkan info penerima dan widget aplikasi ke file
AndroidManifest.xml
.
Menambahkan Glance ke project
Kode awal telah menambahkan versi Glance dan koordinat library ke katalog versi SociaLite: libs.versions.toml
.
libs.versions.toml
[versions]
//..
glance = "1.1.0-beta02"
[libraries]
glance-appwidget = { group = "androidx.glance", name = "glance-appwidget", version.ref = "glance" }
glance-material = { group = "androidx.glance", name = "glance-material3", version.ref = "glance" }
Selain itu, dependensi Glance disertakan dalam file app/build.gradle.kts
SociaLite.
build.gradle.kts
dependencies {
...
implementation(libs.glance.appwidget)
implementation(libs.glance.material)
...
}
- Jika Anda memodifikasi file ini, sinkronkan project untuk mendownload library Glance.
Membuat GlanceAppWidget
dan GlanceAppWidgetReceiver
Android menggunakan penerima siaran untuk memberi tahu SociaLite bahwa widget telah ditambahkan, perlu diperbarui, atau telah dihapus. Glance menyediakan class penerima abstrak, GlanceAppWidgetReceiver, yang memperluas AppWidgetProvider.
Implementasi GlanceAppWidgetReceiver
juga bertanggung jawab untuk menyediakan instance GlanceAppWidget
. Class ini merender composable Glance menjadi tampilan jarak jauh.
Kode awal ini menyertakan dua class : SocialiteAppWidget
, yang memperluas GlanceAppWidget
, dan SocialiteAppWidgetReceiver
, yang memperluas GlanceAppWidgetReceiver
.
Untuk memulai, ikuti langkah-langkah berikut:
- Buka paket
widget
diapp/src/main/java/com/google/android/samples/socialite/
. - Buka class
SociaLiteAppWidget
. Class ini menggantikan metodeprovideGlance
. - Ganti
TODO
dengan panggilan keprovideContent
lalu teruskan fungsi composable widget Anda sebagai parameter. Untuk sekarang, widget hanya menampilkan pesanHello World
, tetapi nanti Anda akan menambahkan lebih banyak fungsi di codelab ini.
package com.google.android.samples.socialite.widget
import android.content.Context
import androidx.glance.GlanceId
import androidx.glance.GlanceTheme
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.provideContent
import androidx.glance.text.Text
class SociaLiteAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
GlanceTheme {
Text("Hello World")
}
}
}
}
- Buka class
SociaLiteAppWidgetReceiver
dalam paketwidget
. Untuk sekarang, penerima Anda menyediakan instanceSociaLiteWidget
, tetapi nanti Anda akan menambahkan lebih banyak fungsi di bagian yang akan datang. - Ganti
TODO
dengan konstruktorSociaLiteAppWidget()
:
package com.google.android.samples.socialite.widget
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
class SociaLiteAppWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = SociaLiteAppWidget()
}
Anda sekarang siap mengonfigurasi Android untuk menampilkan widget Anda dan memungkinkan pengguna untuk menambahkannya ke layar utama mereka.
Menambahkan informasi penyedia widget aplikasi
- Klik kanan res/xml > New > XML resource file.
- Masukkan socialite_widget_info sebagai nama file dan appwidget-provider sebagai elemen root, lalu klik OK. File ini menyertakan metadata untuk
appwidget
Anda yang digunakan olehAppWidgetHost
untuk menampilkan widget pada awalnya. - Tambahkan kode berikut ke file socialite_widget_info.xml:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="3600000"
android:minHeight="128dp"
android:minWidth="128dp"
android:minResizeHeight="128dp"
android:minResizeWidth="128dp"
android:configure="com.google.android.samples.socialite.widget.SociaLiteAppWidgetConfigActivity"
android:widgetFeatures="configuration_optional|reconfigurable"
android:previewImage="@drawable/widget_preview"
android:maxResizeHeight="512dp"
android:maxResizeWidth="512dp"
android:targetCellWidth="2"
android:targetCellHeight="2"
android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>
Tabel berikut memberikan ringkasan atribut dalam kode ini dan menjelaskan masing-masing atribut:
Nama atribut | Deskripsi |
| Widget Anda dapat diubah ukurannya secara vertikal dan horizontal. |
| Menentukan ukuran default widget saat ditambahkan ke layar utama. |
| Mengontrol kapan host widget dapat memutuskan untuk me-refresh widget Anda. Aplikasi Anda dapat memperbarui widget Anda kapan pun widget sedang berjalan dan memiliki informasi baru untuk ditampilkan. |
| Menyetel seberapa kecil Anda dapat mengubah ukuran widget. |
| Menentukan ukuran default minimum widget saat ditambahkan ke layar utama. |
| Menyediakan tata letak awal yang ditampilkan saat Glance merender composable. |
| Menyediakan gambar statis widget untuk ditampilkan di alat pilih widget. |
| Menunjukkan berbagai fitur yang didukung oleh widget. Ini merupakan petunjuk bagi host widget dan tidak benar-benar mengubah perilaku widget. |
| Nama class aktivitas konfigurasi. Ini adalah aktivitas yang nanti mengonfigurasi widget. |
Untuk melihat semua atribut yang tersedia, termasuk fitur di API 31 atau yang lebih baru, lihat AppWidgetProviderInfo
.
Perbarui AndroidManifest
dan uji
Akhirnya, Anda siap untuk memperbarui file AndroidManifest.xml
dan menguji widget Anda. Anda mendefinisikan elemen receiver
sebagai turunan elemen application
dalam file. Penerima ini menangani intent APPWIDGET_UPDATE
dan memberikan metadata appwidget
ke Peluncur Android.
Untuk memulai, ikuti langkah-langkah berikut:
- Buat elemen
receiver
untukSociaLiteAppWidgetReceiver
yang akan diekspor. Salin dan tempel yang berikut ke fileAndroidManifest.xml
setelah elemenapplication
:
<receiver
android:name=".widget.SociaLiteAppWidgetReceiver"
android:exported="true"
android:label="Favorite Contact">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/socialite_widget_info" />
</receiver>
- Kompilasikan dan jalankan aplikasi Anda.
- Setelah aplikasi berjalan, tambahkan widget ke layar utama Anda. Misalnya, di Pixel, tekan lama latar belakang Anda, pilih Widget > SociaLite. Anda akan dapat menambahkan widget ke layar utama Anda.
Widget Anda bertuliskan "Halo Dunia" dan memiliki latar belakang transparan. Harus diakui, ini bukan widget yang paling bagus tampilannya ataupun yang paling fungsional. Di bagian berikutnya, Anda menambahkan tata letak yang lebih rumit dan mempercantik widget dengan percikan warna Desain Material.
4. Memperbaiki desain
Sekarang, Anda memiliki widget statis yang tidak memiliki banyak fitur yang menjadikannya widget yang bagus. Widget yang baik melakukan hal berikut:
- Menjaga konten tetap segar dan singkat, serta menjaga fungsi tetap sederhana.
- Meminimalkan celah yang tidak nyaman melalui tata letak yang dapat diubah ukurannya.
- Menerapkan warna dari latar belakang host widget aplikasi.
Untuk diskusi mendalam tentang apa yang membuat widget bagus, lihat Widget.
Menambahkan scaffold
Sekarang Anda memperbarui widget Anda untuk ditampilkan di komponen Scaffold
Glance.
Scaffold
disediakan oleh library Glance. Ini adalah API slot sederhana untuk menampilkan UI widget dengan TitleBar
. Ini menyetel warna latar belakang ke GlanceTheme.colors.widgetBackground
dan menerapkan padding. Ini akan menjadi komponen tingkat atas Anda.
Untuk memulai, ikuti langkah-langkah berikut:
- Ganti implementasi
SociaLiteAppWidget
dengan kode berikut:
package com.google.android.samples.socialite.widget
import android.content.Context
import androidx.compose.runtime.Composable
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.GlanceTheme
import androidx.glance.ImageProvider
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.components.Scaffold
import androidx.glance.appwidget.components.TitleBar
import androidx.glance.appwidget.provideContent
import androidx.glance.layout.fillMaxSize
import androidx.glance.text.Text
import com.google.android.samples.socialite.R
class SociaLiteAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
GlanceTheme() {
Content()
}
}
}
@Composable
private fun Content() {
Scaffold(titleBar = {TitleBar(startIcon = ImageProvider(R.drawable.ic_launcher_monochrome), title = "SociaLite")},
modifier = GlanceModifier.fillMaxSize()) {
Text("Hello World")
}
}
}
- Untuk melihat pembaruan Anda, jalankan ulang aplikasi lalu tambahkan salinan widget baru ke layar utama Anda.
Ingat, widget adalah tampilan jarak jauh yang ditampilkan oleh host eksternal. Kemudian, Anda menambahkan kemampuan untuk memperbarui widget di dalam aplikasi secara otomatis. Sebelum itu, Anda harus menambahkan widget dari alat pilih widget untuk melihat perubahan kode.
Seperti yang Anda lihat, hasilnya jauh lebih baik, tetapi jika Anda membandingkan widget Anda dengan widget lain, warnanya tampak tidak pas. Di layar utama, widget biasanya akan mengatur warnanya berdasarkan setelan tema pengguna. Dengan token warna dinamis, Anda dapat membuat tema widget Anda beradaptasi dengan wallpaper dan tema perangkat Anda.
Menambahkan warna dinamis
Sekarang Anda menambahkan token warna widgetBackground
ke latar belakang scaffold dan token warna onSurface
ke teks dan Komponen teks TitleBar
. Untuk memperbarui gaya teks, Anda perlu mengimpor classTextStyle
Glance. Untuk memperbarui latar belakang scaffold, Anda menetapkan properti backgroundColor
Scaffold
ke GlanceTheme.colors.widgetBackground
.
Untuk memulai, ikuti langkah-langkah berikut:
- Sertakan impor baru tersebut dalam file SociaLiteAppWidget.kt.
//Add to the imports section of your Kotlin code.
import androidx.glance.text.TextStyle
- Perbarui composable
Content
untuk menambahkanwidgetBackground
.
Scaffold(
titleBar = {
TitleBar(
textColor = GlanceTheme.colors.onSurface,
startIcon = ImageProvider(R.drawable.ic_launcher_monochrome),
title = "SociaLite",
)
},
backgroundColor = GlanceTheme.colors.widgetBackground,
modifier = GlanceModifier.fillMaxSize(),
) {
Text(text = "Hello World", style = TextStyle(color = GlanceTheme.colors.onSurface))
}
- Untuk melihat pembaruan Anda, jalankan ulang aplikasi dan tambahkan salinan widget baru ke layar utama Anda.
Temanya cocok dengan widget lain di layar utama, dan secara otomatis memperbarui warna jika Anda mengubah latar belakang atau mengatur mode gelap. Untuk latar belakang yang benar-benar berwarna, widget beradaptasi dengan bagian latar belakang tempatnya berada.
|
|
Menambahkan status kosong
Sekarang Anda perlu memikirkan tentang status dan mengonfigurasi widget Anda. Saat widget ditambahkan ke layar utama dan memerlukan konfigurasi, sebaiknya tampilkan status kosong. Status kosong meminta pengguna mengonfigurasi widget. Anda menambahkan aktivitas konfigurasi ke widget Anda dan menautkannya dari status kosong.
Codelab ini menyediakan class untuk menyimpan, mengakses, dan mengubah status konfigurasi widget. Anda akan menambahkan kode untuk memperbarui UI widget agar menampilkan status ini, dan membuat tindakan lambda untuk menangani tindakan ketukan pengguna.
Meninjau model widget
Luangkan waktu untuk meninjau class dalam paket com.google.android.samples.socialite.widget.model
.
Ini termasuk class WidgetModel
, serta class WidgetModelDao
dan WidgetModelRepository
. Class ini sudah ada dalam kode awal codelab dan menangani penyimpanan status widget ke database Room
yang mendasarinya. Selain itu, class ini menggunakan Hilt untuk mengelola siklus prosesnya.
Class WidgetModel
berisi widgetId
yang ditetapkan oleh Android, contactId
kontak SociaLite yang ditampilkannya, displayName
dan photo
yang akan ditampilkan, dan Boolean jika kontak memiliki pesan yang belum dibaca. Ini dipakai oleh composable SociaLiteAppWidget
dan ditampilkan di dalam widget.
WidgetModelDao
adalah objek akses data yang mengabstraksi akses ke database SociaLite. WidgetModelRepository
menyediakan fungsi praktis untuk membuat, membaca, memperbarui, dan menghapus instance WidgetModel
. Class ini dibuat oleh Hilt dan dimasukkan ke dalam aplikasi dengan pemasukan dependensi.
- Buka file
WidgetModel.kt
dalam paketmodel
yang ada diapp/src/main/java/com/google/android/samples/socialite/widget/model/
.
Ini adalah class data
dengan anotasi Entity
. Setiap instance widget diberi ID khusus oleh Android dan ID ini digunakan oleh SociaLite sebagai kunci utama untuk data model. Setiap instance model melacak informasi dasar kontak terkait dan apakah ada pesan yang belum terbaca dari kontak tersebut.
@Entity(
foreignKeys = [
ForeignKey(
entity = Contact::class,
parentColumns = ["id"],
childColumns = ["contactId"],
onDelete = ForeignKey.CASCADE,
),
],
indices = [
Index("widgetId"),
Index("contactId"),
],
)
data class WidgetModel(
@PrimaryKey val widgetId: Int,
val contactId: Long,
val displayName: String,
val photo: String,
val unreadMessages: Boolean = false,
) : WidgetState
Status kosong
Anda ingin composable Content
memuat model widget dari WidgetModelRepository
dan menampilkan status kosong jika tidak ada model yang tersedia; jika tidak, Anda ingin menampilkan konten normal widget Anda. Untuk saat ini, ini akan menjadi pesan "Halo Dunia" Anda, tetapi di bagian berikutnya Anda membuat antarmuka yang lebih baik.
Anda akan mengganti composable Content
dengan ekspresi when
yang menampilkan composable ZeroState
, atau placeholder Text
.
- Dalam metode
provideGlance
, di luar composable Anda, dapatkan referensi keWidgetModelRepository
dan ID widget saat ini. Tambahkan baris berikut sebelumprovideContent
dalam metodeSociaLiteAppWidget
provideGlance
.
override suspend fun provideGlance(context: Context, id: GlanceId) {
val widgetId = GlanceAppWidgetManager(context).getAppWidgetId(id)
val repository = WidgetModelRepository.get(context)
Anda mungkin juga perlu menambahkan impor berikut:
import com.google.android.samples.socialite.widget.model.WidgetModel
import com.google.android.samples.socialite.widget.model.WidgetModelRepository
import com.google.android.samples.socialite.widget.model.WidgetState.Loading
import androidx.glance.appwidget.GlanceAppWidgetManager
- Dalam fungsi composable
Content
, tambahkan ID repositori dan widget sebagai parameter, dan gunakan untuk memuat model Anda. Perbarui tanda tangan fungsi composableContent
dan tambahkan baris berikut:
private fun Content(repository: WidgetModelRepository, widgetId: Int) {
val model = repository.loadModel(widgetId).collectAsState(Loading).value
- Jika Android Studio tidak menambahkan impor berikut secara otomatis, tambahkan secara manual:.
import androidx.compose.runtime.collectAsState
Anda juga perlu memperbarui provideGlance
untuk meneruskan ID widget dan repositori ke Content
.
Ganti provideGlance
dengan yang berikut:
override suspend fun provideGlance(context: Context, id: GlanceId) {
val widgetId = GlanceAppWidgetManager(context).getAppWidgetId(id)
val repository = WidgetModelRepository.get(context)
provideContent {
GlanceTheme {
Content(repository, widgetId)
}
}
}
- Dalam fungsi composable
Content
, tentukan status mana yang akan ditampilkan berdasarkan keberadaan suatu model. PindahkanScaffold
konten widget ke composableZeroState
dengan mengganti komponenScaffold
komponen dan isinya dengan blok ini:
when (model) {
is WidgetModel -> {Text("Hello World")}
else -> ZeroState(widgetId)
}
Composable ZeroState
sudah disertakan di kode awal dalam paket com.google.android.samples.socialite.widget.ui
.
- Jika Android Studio tidak secara otomatis mengimpor paket
com.google.android.samples.socialite.widget.ui
, tambahkan kode berikut ke bagian imporSociaLiteAppWidget
.
import com.google.android.samples.socialite.widget.ui.ZeroState
- Untuk melihat pembaruan Anda, jalankan ulang aplikasi dan tambahkan salinan widget baru ke layar utama Anda. Anda akan melihat widget menampilkan komponen ZeroState dan Tombol. Tombol akan membuka aktivitas konfigurasi saat Anda mengkliknya, dan di bagian berikutnya Anda akan memperbarui status widget dari aktivitas ini.
Aktivitas konfigurasi
Tinjau fungsi Composable ZeroState. Fungsi ini ditemukan dalam paket com.google.android.samples.socialite.widget.ui
di file ZeroState.kt
.
@Composable fun ZeroState(widgetId: Int) { val widgetIdKey = ActionParameters.Key<Int>(AppWidgetManager.EXTRA_APPWIDGET_ID) Scaffold( titleBar = { TitleBar( modifier = GlanceModifier.clickable(actionStartActivity(MainActivity::class.java)), textColor = GlanceTheme.colors.onSurface, startIcon = ImageProvider(R.drawable.ic_launcher_monochrome), title = "SociaLite", ) }, backgroundColor = GlanceTheme.colors.widgetBackground, modifier = GlanceModifier.fillMaxSize(), ) { Box(modifier = GlanceModifier.fillMaxSize(), contentAlignment = Alignment.Center) { Button( text = "Select Favorite Contact", onClick = actionStartActivity<SociaLiteAppWidgetConfigActivity>( parameters = actionParametersOf(widgetIdKey to widgetId), ), ) } } }
Composable Scaffold
dipindahkan ke composable ZeroState
. TitleBar
memiliki pengubah clickable
, yang membuka aktivitas utama SociaLite. ZeroState
Anda menggunakan composable Button
Glance untuk menampilkan pesan ajakan (CTA) kepada pengguna dan, ketika diklik, akan membuka aktivitas SociaLiteAppWidgetConfigActivity
dan menyertakan ID widget sebagai ekstra intent. Kedua tindakan ini menggunakan actionStartActivity
fungsi praktis Glance. Untuk informasi lebih lanjut tentang tindakan, lihat Menangani interaksi pengguna.
- Tinjau bagaimana
SociaLiteAppWidgetConfigActivity
digunakan untuk memperbarui konfigurasi widget Anda. Class ini juga merupakan aktivitas konfigurasi untuk widget Anda. Aktivitas konfigurasi membaca ekstra bilangan bulat intent dengan kunciAppWidgetManager.
*EXTRA_APPWIDGET_ID.
*Untuk informasi lebih lanjut tentang aktivitas konfigurasi, lihat Memungkinkan pengguna mengonfigurasi widget aplikasi. - Di
SociaLiteAppWidgetConfigActivity
, gantiTODO
di propertiContactRow
onClick
dengan kode berikut:
{
coroutineScope.launch {
widgetModelRepository.createOrUpdate(
WidgetModel(
appWidgetId,
contact.id,
contact.name,
contact.iconUri.toString(),
false,
),
)
SociaLiteAppWidget().updateAll(this@SociaLiteAppWidgetConfigActivity)
val resultValue = Intent().putExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetId,
)
setResult(RESULT_OK, resultValue)
finish()
}
}
Tambahkan penyertaan berikut jika Android Studio tidak melakukannya secara otomatis
import com.google.android.samples.socialite.widget.model.WidgetModel
import androidx.glance.appwidget.updateAll
import kotlinx.coroutines.launch
Blok kode ini memperbarui status widget Anda. Pertama, blok kode menggunakan repositori untuk menyimpan atau memperbarui WidgetModel
dengan informasi dari kontak yang dipilih. Selanjutnya, blok kode ini memanggil fungsi penangguhan updateAll
. Fungsi ini memperbarui semua widget di layar utama dan dapat dipanggil dari mana saja di aplikasi Anda. Terakhir, blok ini menetapkan hasil aktivitas konfigurasi untuk memberi sinyal bahwa widget berhasil diperbarui.
- Jalankan dan ganti widget Anda di layar utama. Anda akan melihat status kosong yang baru.
- Klik Pilih kontak favorit. Ini membawa Anda ke aktivitas konfigurasi.
- Pilih kontak. Ini memperbarui widget Anda. Namun, widget belum menampilkan kontak favorit Anda karena Anda menambahkan kemampuan itu di bagian berikutnya.
Mengelola data widget
- Buka alat App inspection, hubungkan ke suatu proses jika perlu, dan pilih tab Database inspector untuk melihat isi database aplikasi.
- Pilih kontak favorit di widget dan lihat apakah diperbarui menjadi "Halo Dunia". Kembali ke alat App inspection, Anda akan melihat tabModel widget tab dengan satu entri untuk widget Anda. Anda mungkin perlu me-refresh tabel atau menekan Info terbaru langsung untuk melihat perubahannya.
- Tambahkan widget lain dan pilih kontak lain. Anda mungkin harus menekan Refresh tabel atau Info terbaru langsung to untuk melihat model baru.
- Hapus widget dan perhatikan bahwa model tertinggal dalam database setelah widget dihapus.
Anda dapat memperbarui SociaLiteAppWidgetReceiver
untuk membersihkan database Anda ketika widget dihapus dengan mengganti onDeleted
.
Untuk membersihkan model widget yang usang, Anda dapat memanggil WidgetModelRepository.cleanupWidgetModels
. Class repositori dikelola oleh Hilt dan Anda perlu menggunakan pemasukan dependensi untuk mengakses instance-nya.
- Dalam
SociaLiteAppWidgetReceiver
, tambahkan instanceAndroidEntryPoint
Anotasi Hilt ke deklarasi class penerima Anda dan memasukkanWidgetModelRepository
. - Panggil
WidgetModelRepository.cleanupWidgetModels
dalam metode penggantian untukonDeleted
.
Kode akan terlihat seperti ini:
package com.google.android.samples.socialite.widget
import android.content.Context
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import com.google.android.samples.socialite.widget.model.WidgetModelRepository
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class SociaLiteAppWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = SociaLiteAppWidget()
@Inject
lateinit var repository: WidgetModelRepository
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds)
repository.cleanupWidgetModels(context)
}
}
- Jalankan kembali aplikasi. Anda akan melihat bahwa baris model dihapus di App inspector jika widget dihapus dari layar utama.
5. Menambahkan UI Kontak dan mengupdate saat pesan baru tiba
Anda telah memasuki bagian akhir codelab ini. Untuk bagian ini, Anda menerapkan UI kontak akhir untuk widget dan memperbaruinya jika ada pesan yang belum terbaca untuk kontak tersebut.
- Tinjau class
WidgetModelRepository
Anda dalam paket model.
Di sinilah Anda memiliki metode praktis updateUnreadMessagesForContact
; metode ini memperbarui widget yang terkait dengan ID kontak.
//Don't add this code.
fun updateUnreadMessagesForContact(contactId: Long, unread: Boolean) {
coroutineScope.launch {
widgetModelDao.modelsForContact(contactId).filterNotNull().forEach { model ->
widgetModelDao.update(
WidgetModel(model.widgetId, model.contactId, model.displayName, model.photo, unread)
)
SociaLiteAppWidget().updateAll(appContext)
}
}
}
Metode ini memiliki dua parameter: contactId
, tID kontak yang sedang diperbarui dan unread
, Boolean status pesan yang belum dibaca. Metode ini menggunakan WidgetModelDao
, untuk menemukan semua model widget yang menampilkan kontak ini dan memperbarui model dengan status baca yang baru. Lalu, fungsi ini memanggil metode SociaLiteAppWidget().updateAll
yang disediakan Glance untuk memperbarui semua widget di layar utama pengguna.
Sekarang setelah Anda memahami cara widget dan statusnya diperbarui, Anda dapat membuat UI kontak, mengirim pesan, dan melihatnya diperbarui. Untuk melakukannya, perbarui SociaLiteAppWidget
dengan FavoriteContact
composable di tata letak widget Anda. Dalam tata letak ini, Anda juga memeriksa apakah Anda harus menampilkan No new messages
atau New Messages!
.
- Tinjau file
FavoriteContact.kt
dalam paketcom.google.android.samples.socialite.widget.ui
.
//Don't add this code.
@Composable
fun FavoriteContact(model: WidgetModel, onClick: Action) {
Column(
modifier = GlanceModifier.fillMaxSize().clickable(onClick)
.background(GlanceTheme.colors.widgetBackground).appWidgetBackground()
.padding(bottom = 8.dp),
verticalAlignment = Alignment.Vertical.Bottom,
horizontalAlignment = Alignment.Horizontal.CenterHorizontally,
) {
Image(
modifier = GlanceModifier.fillMaxWidth().wrapContentHeight().defaultWeight()
.cornerRadius(16.dp),
provider = ImageProvider(model.photo.toUri()),
contentScale = ContentScale.Crop,
contentDescription = model.displayName,
)
Column(
modifier = GlanceModifier.fillMaxWidth().wrapContentHeight().padding(top = 4.dp),
verticalAlignment = Alignment.Vertical.Bottom,
horizontalAlignment = Alignment.Horizontal.CenterHorizontally,
) {
Text(
text = model.displayName,
style = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 24.sp,
color = (GlanceTheme.colors.onSurface),
),
)
Text(
text = if (model.unreadMessages) "New Message!" else "No messages",
style = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
color = (GlanceTheme.colors.onSurface),
),
)
}
}
}
- Ganti
Text("Hello World")
dalam composableContent
SociaLiteAppWidget
dengan panggilan ke composableFavoriteContact
.
Composable ini akan mengambil WidgetModel dan Action yang dibuat oleh actionStartActivity
fungsi Glance.
- Tambahkan panggilan ke blok
when
sebelumZeroState
jika modelnya bukanWidgetModel
.
when (model) {
is WidgetModel -> FavoriteContact(model = model, onClick = actionStartActivity(
Intent(LocalContext.current.applicationContext, MainActivity::class.java)
.setAction(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.setData("https://socialite.google.com/chat/${model.contactId}".toUri()))
)
else -> ZeroState(widgetId)
}
- Jika Android Studio tidak otomatis menambah paket ini, lakukan impor paket tersebut secara manual:
import com.google.android.samples.socialite.widget.ui.FavoriteContact
import androidx.glance.appwidget.action.actionStartActivity
import android.content.Intent
import com.google.android.samples.socialite.MainActivity
import androidx.core.net.toUri
- Jalankan aplikasi Anda.
- Pilih kontak favorit, kirim pesan, dan segera keluar dari aplikasi sebelum mereka merespons. Saat respons tiba, status widget akan berubah.
- Klik widget untuk membuka chat dan melihat bahwa status diperbarui lagi saat Anda keluar ke layar utama.
6. Selamat
Anda sudah berhasil menyelesaikan codelab dan mempelajari cara menulis widget menggunakan Glance! Anda akan merasa nyaman membuat widget cantik yang terlihat bagus di banyak layar utama, menangani input pengguna, dan memperbarui dirinya sendiri.
Untuk mendapatkan kode solusi main
, ikuti langkah-langkah berikut:
- Jika Anda sudah mendownload SociaLite, jalankan perintah ini:
git checkout main
- Jika Anda belum mendownload SociaLite, download kode lagi untuk melihat cabang
main
:
git clone git@github.com:android/socialite.git