1. Pengantar
Dengan layar besar, Anda dapat membuat tata letak dan UI aplikasi yang meningkatkan pengalaman pengguna dan meningkatkan produktivitas pengguna. Namun, jika aplikasi Anda didesain untuk layar kecil ponsel non-foldable, aplikasi tersebut mungkin tidak memanfaatkan ruang layar tambahan yang ditawarkan oleh tablet, perangkat foldable, dan perangkat ChromeOS.
Mengupdate aplikasi untuk mengoptimalkan layar besar dapat menghabiskan waktu dan biaya, terutama untuk aplikasi lama berdasarkan beberapa aktivitas.
Penyematan aktivitas, yang diperkenalkan di Android 12L (API level 32), memungkinkan aplikasi berbasis aktivitas menampilkan beberapa aktivitas secara bersamaan di perangkat layar besar untuk membuat tata letak dua panel seperti daftar-detail. Tidak perlu melakukan coding ulang Kotlin atau Java. Anda menambahkan beberapa dependensi, membuat file konfigurasi XML, mengimplementasikan penginisialisasi, dan membuat beberapa tambahan ke manifes aplikasi. Cara lain, jika Anda lebih suka menggunakan kode, cukup tambahkan beberapa panggilan Jetpack WindowManager API ke metode onCreate()
dari aktivitas utama aplikasi Anda.
Prasyarat
Untuk menyelesaikan codelab ini, Anda memerlukan pengalaman berikut:
- Membuat aplikasi Android
- Bekerja dengan aktivitas
- Menulis XML
- Bekerja di Android Studio, termasuk penyiapan perangkat virtual
Yang akan Anda build
Dalam codelab ini, Anda akan mengupdate aplikasi berbasis aktivitas untuk mendukung tata letak dua panel dinamis yang mirip dengan SlidingPaneLayout
. Pada layar kecil, aplikasi menempatkan (menumpuk) aktivitas di atas satu sama lain di jendela tugas.
Pada perangkat layar besar, aplikasi menampilkan dua aktivitas di layar secara bersamaan, baik secara berdampingan atau atas dan bawah berdasarkan spesifikasi Anda.
Yang akan Anda pelajari
Cara menerapkan penyematan aktivitas dengan dua cara:
- Dengan file konfigurasi XML
- Menggunakan panggilan Jetpack WindowManager API
Yang Anda butuhkan
- Versi terbaru Android Studio
- Ponsel atau emulator Android
- Tablet atau emulator kecil Android
- Tablet atau emulator besar Android
2. Penyiapan
Mendapatkan aplikasi contoh
Langkah 1: Membuat clone repo
Buat clone repositori Git codelab layar besar:
git clone https://github.com/android/large-screen-codelabs
atau download dan batalkan pengarsipan file zip codelab layar besar:
Langkah 2: Memeriksa file sumber codelab
Buka folder activity-embedding
.
Langkah 3: Membuka project codelab
Di Android Studio, buka project Kotlin atau Java
Folder activity-embedding
di file zip dan repo berisi dua project Android Studio: satu di Kotlin, satu di Java. Buka project pilihan Anda. Cuplikan codelab tersedia dalam kedua bahasa.
Membuat perangkat virtual
Jika Anda tidak memiliki ponsel Android, tablet kecil, atau tablet besar di API level 32 atau yang lebih tinggi, buka Pengelola Perangkat di Android Studio dan buat perangkat virtual berikut yang Anda perlukan:
- Ponsel — Pixel 6, API level 32 atau yang lebih tinggi
- Tablet kecil — 7 WSVGA (Tablet), API level 32 atau lebih tinggi
- Tablet besar — Pixel C, API level 32 atau lebih tinggi
3. Menjalankan aplikasi
Aplikasi contoh menampilkan daftar item. Saat pengguna memilih item, aplikasi akan menampilkan informasi tentang item tersebut.
Aplikasi ini terdiri dari tiga aktivitas:
ListActivity
— Berisi daftar item diRecyclerView
DetailActivity
— Menampilkan informasi tentang item daftar saat item dipilih dari daftarSummaryActivity
— Menampilkan ringkasan informasi saat item daftar Ringkasan dipilih
Perilaku tanpa penyematan aktivitas
Jalankan aplikasi contoh untuk melihat perilakunya tanpa penyematan aktivitas:
- Jalankan aplikasi contoh di tablet besar atau emulator Pixel C Anda. Aktivitas utama (daftar) muncul:
- Pilih item daftar untuk meluncurkan aktivitas sekunder (detail). Aktivitas detail menempatkan aktivitas daftar:
- Putar tablet ke orientasi lanskap. Aktivitas sekunder masih menempatkan aktivitas utama dan menempati seluruh tampilan:
- Pilih kontrol kembali (panah menghadap ke kiri di panel aplikasi) untuk kembali ke daftar.
- Pilih item terakhir dalam daftar, Ringkasan, untuk meluncurkan aktivitas ringkasan sebagai aktivitas sekunder. Aktivitas ringkasan menempatkan aktivitas daftar:
- Putar tablet ke orientasi lanskap. Aktivitas sekunder masih menempatkan aktivitas utama dan menempati seluruh tampilan:
Perilaku dengan penyematan aktivitas
Setelah menyelesaikan codelab ini, orientasi lanskap akan menampilkan aktivitas daftar dan detail secara berdampingan dalam tata letak daftar-detail:
Namun, Anda akan mengonfigurasi ringkasan agar menampilkan layar penuh, meskipun aktivitas diluncurkan dari dalam pemisahan. Ringkasan akan menempatkan pemisahan:
4. Latar belakang
Penyematan aktivitas memisahkan jendela tugas aplikasi menjadi dua penampung: primer dan sekunder. Aktivitas apa pun dapat memulai pemisahan dengan meluncurkan aktivitas lain. Aktivitas yang dimulai lebih awal menempati penampung utama; aktivitas yang diluncurkan, yaitu aktivitas sekunder.
Aktivitas utama dapat meluncurkan aktivitas tambahan di penampung sekunder. Aktivitas di kedua penampung kemudian dapat meluncurkan aktivitas di penampungnya masing-masing. Setiap penampung dapat berisi tumpukan aktivitas. Untuk mengetahui informasi selengkapnya, lihat panduan developer Penyematan aktivitas.
Anda mengonfigurasi aplikasi untuk mendukung penyematan aktivitas dengan membuat file konfigurasi XML atau dengan melakukan panggilan Jetpack WindowManager API. Kita akan mulai dengan pendekatan konfigurasi XML.
5. Konfigurasi XML
Penampung dan pemisahan penyematan aktivitas dibuat dan dikelola oleh library Jetpack WindowManager berdasarkan aturan pemisahan yang Anda buat di file konfigurasi XML.
Menambahkan dependensi WindowManager
Aktifkan aplikasi contoh untuk mengakses library WindowManager dengan menambahkan dependensi library ke file build.gradle
level modul aplikasi, misalnya:
build.gradle
implementation 'androidx.window:window:1.2.0'
Memberi tahu sistem
Beri tahu sistem bahwa aplikasi Anda telah menerapkan penyematan aktivitas.
Tambahkan properti android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
ke elemen <application>
dari file manifes aplikasi, dan tetapkan nilai ke true:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<property
android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED"
android:value="true" />
</application>
</manifest>
Produsen perangkat (OEM) menggunakan setelan untuk mengaktifkan kemampuan kustom untuk aplikasi yang mendukung penyematan aktivitas. Misalnya, perangkat dapat membuat tampilan lebar aktivitas khusus potret (lihat android:screenOrientation
) pada tampilan lanskap untuk mengorientasikan aktivitas agar transisi berjalan lancar ke aktivitas yang menyematkan tata letak dua panel:
Membuat file konfigurasi
Buat file resource XML bernama main_split_config.xml
di folder res/xml
aplikasi Anda dengan resources
sebagai elemen root.
Ubah namespace XML menjadi:
main_split_config.xml
xmlns:window="http://schemas.android.com/apk/res-auto"
Aturan pasangan pemisahan
Tambahkan aturan pemisahan berikut ke file konfigurasi:
main_split_config.xml
<!-- Define a split for the named activity pair. -->
<SplitPairRule
window:splitRatio="0.33"
window:splitMinWidthDp="840"
window:finishPrimaryWithSecondary="never"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".ListActivity"
window:secondaryActivityName=".DetailActivity"/>
</SplitPairRule>
Aturan tersebut melakukan hal berikut:
- Mengonfigurasi opsi pemisahan untuk aktivitas yang berbagi pemisahan:
splitRatio
— Menentukan jumlah jendela tugas yang ditempati oleh aktivitas utama (33%), menyisakan ruang yang tersisa untuk aktivitas sekunder.splitMinWidthDp
— Menentukan lebar tampilan minimum (840) yang diperlukan agar kedua aktivitas berada di layar secara bersamaan. Unit adalah piksel yang tidak bergantung tampilan (dp).
finishPrimaryWithSecondary
— Menentukan apakah aktivitas di penampung pemisahan utama selesai (tidak pernah) saat semua aktivitas dalam penampung sekunder selesai.finishSecondaryWithPrimary
— Menentukan apakah aktivitas di penampung pemisahan sekunder selesai (selalu) saat semua aktivitas di aktivitas penampung utama selesai.- Menyertakan filter pemisahan yang menentukan aktivitas yang berbagi pemisahan jendela tugas. Aktivitas utamanya adalah
ListActivity
; sekundernya adalahDetailActivity
.
Aturan placeholder
Aktivitas placeholder menempati penampung sekunder dari pemisahan aktivitas saat tidak ada konten yang tersedia untuk penampung tersebut, misalnya, saat pemisahan daftar-detail terbuka tetapi item daftar belum dipilih. (Untuk mengetahui informasi selengkapnya, lihat Placeholder di panduan developer Penyematan aktivitas.)
Tambahkan aturan placeholder berikut ke file konfigurasi:
main_split_config.xml
<!-- Automatically launch a placeholder for the detail activity. -->
<SplitPlaceholderRule
window:placeholderActivityName=".PlaceholderActivity"
window:splitRatio="0.33"
window:splitMinWidthDp="840"
window:finishPrimaryWithPlaceholder="always"
window:stickyPlaceholder="false">
<ActivityFilter
window:activityName=".ListActivity"/>
</SplitPlaceholderRule>
Aturan tersebut melakukan hal berikut:
- Mengidentifikasi aktivitas placeholder,
PlaceholderActivity
(kita akan membuat aktivitas ini pada langkah berikutnya) - Mengonfigurasi opsi untuk placeholder:
splitRatio
— Menentukan jumlah jendela tugas yang ditempati oleh aktivitas utama (33%), menyisakan ruang untuk placeholder yang tersisa. Biasanya, nilai ini harus sesuai dengan rasio pemisahan aturan pasangan pemisahan yang dikaitkan dengan placeholder.splitMinWidthDp
— Menentukan lebar tampilan minimum (840) yang diperlukan agar placeholder muncul di layar dengan aktivitas utama. Biasanya, nilai ini harus sesuai dengan lebar minimum aturan pasangan pemisahan yang dikaitkan dengan placeholder. Unit adalah piksel yang tidak bergantung tampilan (dp).finishPrimaryWithPlaceholder
— Menentukan apakah aktivitas di penampung pemisahan utama selesai (selalu) saat placeholder selesai.stickyPlaceholder
— Menunjukkan apakah placeholder harus tetap berada di layar (false) sebagai aktivitas teratas saat ukuran layar diperkecil ke tampilan satu panel dari layar dua panel, misalnya, saat perangkat foldable dilipat.- Menyertakan filter aktivitas yang menentukan aktivitas (
ListActivity
) yang akan digunakan oleh placeholder untuk berbagi jendela tugas.
Placeholder menggantikan aktivitas sekunder aturan pasangan pemisahan yang aktivitas utamanya sama dengan aktivitas di filter aktivitas placeholder (lihat "Aturan pasangan pemisahan" di bagian "Konfigurasi XML" di codelab ini).
Aturan aktivitas
Aturan aktivitas adalah aturan tujuan umum. Aktivitas yang Anda inginkan untuk menempati seluruh jendela tugas—yaitu, tidak pernah menjadi bagian dari pemisah—dapat ditentukan dengan aturan aktivitas. (Untuk mengetahui informasi selengkapnya, lihat Modal jendela penuh di panduan developer Penyematan aktivitas.)
Kita akan membuat aktivitas ringkasan mengisi seluruh jendela tugas, yang menempatkan pemisahan. Navigasi kembali akan kembali ke pemisahan.
Tambahkan aturan aktivitas berikut ke file konfigurasi:
main_split_config.xml
<!-- Activities that should never be in a split. -->
<ActivityRule
window:alwaysExpand="true">
<ActivityFilter
window:activityName=".SummaryActivity"/>
</ActivityRule>
Aturan tersebut melakukan hal berikut:
- Mengidentifikasi aktivitas yang harus ditampilkan jendela penuh (
SummaryActivity).
- Mengonfigurasi opsi untuk aktivitas:
alwaysExpand
— Menetapkan apakah aktivitas harus diperluas atau tidak untuk mengisi semua ruang tampilan yang tersedia.
File sumber
File konfigurasi XML yang sudah selesai akan terlihat seperti ini:
main_split_config.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:window="http://schemas.android.com/apk/res-auto">
<!-- Define a split for the named activity pair. -->
<SplitPairRule
window:splitRatio="0.33"
window:splitMinWidthDp="840"
window:finishPrimaryWithSecondary="never"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".ListActivity"
window:secondaryActivityName=".DetailActivity"/>
</SplitPairRule>
<!-- Automatically launch a placeholder for the detail activity. -->
<SplitPlaceholderRule
window:placeholderActivityName=".PlaceholderActivity"
window:splitRatio="0.33"
window:splitMinWidthDp="840"
window:finishPrimaryWithPlaceholder="always"
window:stickyPlaceholder="false">
<ActivityFilter
window:activityName=".ListActivity"/>
</SplitPlaceholderRule>
<!-- Activities that should never be in a split. -->
<ActivityRule
window:alwaysExpand="true">
<ActivityFilter
window:activityName=".SummaryActivity"/>
</ActivityRule>
</resources>
Membuat aktivitas placeholder
Anda perlu membuat aktivitas baru agar berfungsi sebagai placeholder yang ditentukan dalam file konfigurasi XML. Aktivitas ini bisa sangat sederhana, hanya sesuatu yang mengindikasikan pengguna bahwa konten akan muncul di sini.
Buat aktivitas di folder sumber utama aplikasi contoh.
Di Android Studio, lakukan hal berikut:
- Klik kanan (tombol sekunder–klik) folder sumber aplikasi contoh,
com.example.activity_embedding
- Pilih New > Activity > Empty Views Activity
- Beri nama aktivitas PlaceholderActivity
- Pilih Finish
Android Studio membuat aktivitas dalam paket aplikasi contoh, menambahkan aktivitas ke file manifes aplikasi, dan membuat file resource tata letak bernama activity_placeholder.xm
l di folder res/layout
.
- Di file
AndroidManifest.xml
aplikasi contoh, tetapkan label untuk aktivitas placeholder ke string kosong:
AndroidManifest.xml
<activity
android:name=".PlaceholderActivity"
android:exported="false"
android:label="" />
- Ganti konten file tata letak
activity_placeholder.xml
di folderres/layout
dengan yang berikut ini:
activity_placeholder.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/gray"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PlaceholderActivity">
<TextView
android:id="@+id/textViewPlaceholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/placeholder_text"
android:textSize="36sp"
android:textColor="@color/obsidian"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Terakhir, tambahkan resource string berikut ke file resource
strings.xml
di folderres/values
:
strings.xml
<string name="placeholder_text">Placeholder</string>
Membuat penginisialisasi
Komponen RuleController
WindowManager menguraikan aturan yang ditentukan dalam file konfigurasi XML dan membuat aturan tersedia untuk sistem.
Initializer library Jetpack Startup memungkinkan RuleController
mengakses file konfigurasi.
Library Startup melakukan inisialisasi komponen saat aplikasi dimulai. Inisialisasi harus terjadi sebelum aktivitas dimulai sehingga RuleController
memiliki akses ke aturan pemisahan dan dapat menerapkannya jika diperlukan.
Menambahkan dependensi library Startup
Untuk mengaktifkan fungsionalitas startup, tambahkan dependensi library Startup ke file build.gradle
level modul aplikasi contoh, misalnya:
build.gradle
implementation 'androidx.startup:startup-runtime:1.1.1'
Mengimplementasikan penginisialisasi untuk RuleController
Buat implementasi antarmuka Initializer Startup.
Di Android Studio, lakukan hal berikut:
- Klik kanan (tombol sekunder–klik) folder sumber aplikasi contoh,
com.example.activity_embedding
- Pilih New > Kotlin Class/File atau New > Java Class
- Beri nama class SplitInitializer
- Tekan Enter — Android Studio akan membuat class dalam paket aplikasi contoh.
- Ganti konten file class dengan berikut ini:
SplitInitializer.kt
package com.example.activity_embedding
import android.content.Context
import androidx.startup.Initializer
import androidx.window.embedding.RuleController
class SplitInitializer : Initializer<RuleController> {
override fun create(context: Context): RuleController {
return RuleController.getInstance(context).apply {
setRules(RuleController.parseRules(context, R.xml.main_split_config))
}
}
override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}
SplitInitializer.java
package com.example.activity_embedding;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.startup.Initializer;
import androidx.window.embedding.RuleController;
import java.util.Collections;
import java.util.List;
public class SplitInitializer implements Initializer<RuleController> {
@NonNull
@Override
public RuleController create(@NonNull Context context) {
RuleController ruleController = RuleController.getInstance(context);
ruleController.setRules(
RuleController.parseRules(context, R.xml.main_split_config)
);
return ruleController;
}
@NonNull
@Override
public List<Class<? extends Initializer<?>>> dependencies() {
return Collections.emptyList();
}
}
Penginisialisasi membuat aturan terpisah tersedia untuk komponen RuleController
dengan meneruskan ID file resource XML yang berisi definisi (main_split_config
) ke metode parseRules()
komponen. Metode setRules()
menambahkan aturan yang diuraikan ke RuleController
.
Membuat penyedia inisialisasi
Penyedia memanggil proses inisialisasi aturan pemisahan.
Tambahkan androidx.startup.InitializationProvider
ke elemen <application>
file manifes aplikasi contoh sebagai penyedia, dan referensikan SplitInitializer
:
AndroidManifest.xml
<provider android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- Make SplitInitializer discoverable by InitializationProvider. -->
<meta-data android:name="${applicationId}.SplitInitializer"
android:value="androidx.startup" />
</provider>
InitializationProvider
melakukan inisialisasi SplitInitializer
, yang kemudian memanggil metode RuleController
yang mengurai file konfigurasi XML (main_split_config.xml
) dan menambahkan aturan ke RuleController
(lihat "Mengimplementasikan penginisialisasi untuk RuleController" di atas).
InitializationProvider
menemukan dan melakukan inisialisasi SplitInitializer
sebelum metode onCreate()
aplikasi dieksekusi sehingga, aturan pemisahan berlaku saat aktivitas aplikasi utama dimulai.
File sumber
Berikut adalah manifes aplikasi yang sudah selesai:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Activity_Embedding"
tools:targetApi="32">
<activity
android:name=".ListActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DetailActivity"
android:exported="false"
android:label="" />
<activity
android:name=".SummaryActivity"
android:exported="false"
android:label="" />
<activity
android:name=".PlaceholderActivity"
android:exported="false"
android:label="" />
<property
android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED"
android:value="true" />
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- Make SplitInitializer discoverable by InitializationProvider. -->
<meta-data
android:name="${applicationId}.SplitInitializer"
android:value="androidx.startup" />
</provider>
</application>
</manifest>
Pintasan inisialisasi
Jika terbiasa menggabungkan konfigurasi XML dengan WindowManager API, Anda dapat menghilangkan penginisialisasi library Startup dan penyedia manifes untuk implementasi yang jauh lebih sederhana.
Setelah Anda membuat file konfigurasi XML, lakukan hal berikut:
Langkah 1: Membuat subclass dari Application
Subclass aplikasi Anda akan menjadi class pertama yang dibuat instance-nya saat proses untuk aplikasi Anda dibuat. Anda akan menambahkan aturan terpisah ke RuleController
di metode onCreate()
subclass untuk memastikan aturan berlaku sebelum aktivitas apa pun diluncurkan.
Di Android Studio, lakukan hal berikut:
- Klik kanan (tombol sekunder–klik) folder sumber aplikasi contoh,
com.example.activity_embedding
- Pilih New > Kotlin Class/File atau New > Java Class
- Beri nama class SampleApplication
- Tekan Enter — Android Studio akan membuat class dalam paket aplikasi contoh
- Perluas class dari supertype
Application
SampleApplication.kt
package com.example.activity_embedding
import android.app.Application
/**
* Initializer for activity embedding split rules.
*/
class SampleApplication : Application() {
}
SampleApplication.java
package com.example.activity_embedding;
import android.app.Application;
/**
* Initializer for activity embedding split rules.
*/
public class SampleApplication extends Application {
}
Langkah 2: Melakukan inisialisasi RuleController
Tambahkan aturan terpisah dari file konfigurasi XML ke RuleController
di metode onCreate()
subclass aplikasi Anda.
Untuk menambahkan aturan ke RuleController
, lakukan hal berikut:
- Dapatkan instance singleton
RuleController
- Gunakan metode
parseRules()
Java statis atau pendamping Kotlin dariRuleController
untuk mengurai file XML - Tambahkan aturan yang diuraikan ke
RuleController
dengan metodesetRules()
SampleApplication.kt
override fun onCreate() {
super.onCreate()
RuleController.getInstance(this)
.setRules(RuleController.parseRules(this, R.xml.main_split_config))
}
SampleApplication.java
@Override
public void onCreate() {
super.onCreate();
RuleController.getInstance(this)
.setRules(RuleController.parseRules(this, R.xml.main_split_config));
}
Langkah 3: Menambahkan nama subclass ke manifes
Tambahkan nama subclass Anda ke elemen <application>
dari manifes aplikasi:
AndroidManifest.xml
<application
android:name=".SampleApplication"
. . .
Menjalankan aplikasi
Build dan jalankan aplikasi contoh.
Pada ponsel non-foldable, aktivitas akan selalu ditumpuk—bahkan dalam orientasi lanskap:
Di Android 13 (API level 33) dan yang lebih rendah, penyematan aktivitas tidak diaktifkan di ponsel non-foldable, terlepas dari spesifikasi lebar minimum pemisahan.
Dukungan untuk penyematan aktivitas untuk ponsel non-foldable pada API level yang lebih tinggi bergantung pada apakah produsen perangkat telah mengaktifkan penyematan aktivitas.
Pada tablet kecil atau emulator 7 WSVGA (Tablet), kedua aktivitas ditumpuk dalam orientasi potret, tetapi keduanya muncul berdampingan dalam orientasi lanskap:
Pada tablet besar atau emulator Pixel C, aktivitas ditumpuk dalam orientasi potret (lihat "Rasio aspek" di bawah), tetapi akan muncul berdampingan dalam orientasi lanskap:
Ringkasan menampilkan layar penuh dalam lanskap meskipun diluncurkan dari dalam pemisahan:
Rasio aspek
Pemisahan aktivitas dikontrol oleh rasio aspek tampilan, selain lebar minimum pemisahan. Atribut splitMaxAspectRatioInPortrait
dan splitMaxAspectRatioInLandscape
menentukan rasio aspek tampilan maksimum (height:width) untuk pemisahan aktivitas yang ditampilkan. Atribut mewakili properti maxAspectRatioInPortrait
dan maxAspectRatioInLandscape
dari SplitRule
.
Jika rasio aspek tampilan melebihi nilai di salah satu orientasi, pemisahan akan dinonaktifkan terlepas dari lebar tampilan. Nilai default untuk orientasi potret adalah 1,4 (lihat SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
) yang mencegah tampilan tinggi dan sempit agar tidak menampilkan pemisahan. Secara default, pemisahan selalu diizinkan dalam orientasi lanskap (lihat SPLIT_MAX_ASPECT_RATIO_LANDSCAPE_DEFAULT
).
Emulator Pixel C memiliki lebar tampilan potret 900 dp, yang lebih lebar dari setelan splitMinWidthDp
dalam file konfigurasi XML aplikasi contoh, sehingga emulator harus menampilkan pemisahan aktivitas. Namun, rasio aspek Pixel C dalam mode potret lebih besar dari 1,4, yang mencegah pemisahan aktivitas ditampilkan dalam orientasi potret.
Anda dapat menyetel rasio aspek maksimum untuk tampilan potret dan lanskap dalam file konfigurasi XML di elemen SplitPairRule
dan SplitPlaceholderRule
, misalnya:
main_split_config.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:window="http://schemas.android.com/apk/res/android">
<!-- Define a split for the named activity pair. -->
<SplitPairRule
. . .
window:splitMaxAspectRatioInPortrait="alwaysAllow"
window:splitMaxAspectRatioInLandscape="alwaysDisallow"
. . .
</SplitPairRule>
<SplitPlaceholderRule
. . .
window:splitMaxAspectRatioInPortrait="alwaysAllow"
window:splitMaxAspectRatioInLandscape="alwaysDisallow"
. . .
</SplitPlaceholderRule>
</resources>
Di tablet besar dengan lebar tampilan potret yang lebih besar atau sama dengan 840 dp atau emulator Pixel C, aktivitas tersebut berdampingan dalam orientasi potret, tetapi ditumpuk dalam orientasi lanskap:
Kredit ekstra
Coba tetapkan rasio aspek di aplikasi contoh seperti yang ditunjukkan di atas untuk orientasi potret dan lanskap. Uji setelan dengan tablet besar Anda (jika lebar potret adalah 840 dp atau lebih) atau emulator Pixel C. Anda akan melihat pemisahan aktivitas dalam orientasi potret, tetapi tidak dalam orientasi lanskap.
Tentukan rasio aspek potret tablet besar Anda (rasio aspek Pixel C sedikit lebih besar dari 1,4). Tetapkan splitMaxAspectRatioInPortrait
ke nilai yang lebih tinggi dan lebih rendah dari rasio aspek. Jalankan aplikasi, dan lihat hasil yang Anda dapatkan.
6. WindowManager API
Anda dapat mengaktifkan penyematan aktivitas sepenuhnya dalam kode dengan satu metode yang dipanggil dari dalam metode onCreate()
aktivitas yang memulai pemisahan. Jika Anda lebih suka menggunakan kode daripada XML, ini adalah cara yang tepat.
Menambahkan dependensi WindowManager
Aplikasi memerlukan akses ke library WindowManager baik Anda membuat implementasi berbasis XML atau menggunakan panggilan API. Lihat bagian "Konfigurasi XML" di codelab ini untuk mengetahui cara menambahkan dependensi WindowManager ke aplikasi Anda.
Memberi tahu sistem
Terlepas dari apakah Anda menggunakan file konfigurasi XML atau panggilan WindowManager API, aplikasi harus memberi tahu sistem bahwa aplikasi telah menerapkan penyematan aktivitas. Lihat bagian "Konfigurasi XML" di codelab ini untuk mengetahui cara menginformasikan sistem penerapan Anda.
Membuat class untuk mengelola pemisahan
Di bagian codelab ini, Anda akan menerapkan pemisahan aktivitas sepenuhnya dalam satu metode objek statis atau pendamping yang akan Anda panggil dari aktivitas utama aplikasi contoh, ListActivity
.
Buat class bernama SplitManager
dengan metode bernama createSplit
yang menyertakan parameter context
(beberapa panggilan API memerlukan parameter):
SplitManager.kt
class SplitManager {
companion object {
fun createSplit(context: Context) {
}
}
SplitManager.java
class SplitManager {
static void createSplit(Context context) {
}
}
Panggil metode dalam metode onCreate()
subclass dari class Application
.
Untuk mengetahui detail tentang alasan dan cara membuat subclass Application
, lihat "Pintasan inisialisasi" di bagian "Konfigurasi XML" di codelab ini.
SampleApplication.kt
package com.example.activity_embedding
import android.app.Application
/**
* Initializer for activity embedding split rules.
*/
class SampleApplication : Application() {
override fun onCreate() {
super.onCreate()
SplitManager.createSplit(this)
}
}
SampleApplication.java
package com.example.activity_embedding;
import android.app.Application;
/**
* Initializer for activity embedding split rules.
*/
public class SampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SplitManager.createSplit(this);
}
}
Membuat aturan pemisahan:
API yang diperlukan:
SplitPairRule
menentukan aturan pemisahan untuk sepasang aktivitas.
SplitPairRule.Builder
membuat SplitPairRule
. Builder mengambil kumpulan objek SplitPairFilter
sebagai argumen. Filter menentukan waktu untuk menerapkan aturan.
Anda mendaftarkan aturan dengan instance singleton komponen RuleController
, yang membuat aturan pemisahan tersedia untuk sistem.
Untuk membuat aturan terpisah, lakukan hal berikut:
- Buat filter pasangan pemisahan yang mengidentifikasi
ListActivity
danDetailActivity
sebagai aktivitas yang berbagi pemisahan:
SplitManager.kt / createSplit()
val splitPairFilter = SplitPairFilter(
ComponentName(context, ListActivity::class.java),
ComponentName(context, DetailActivity::class.java),
null
)
SplitManager.java / createSplit()
SplitPairFilter splitPairFilter = new SplitPairFilter(
new ComponentName(context, ListActivity.class),
new ComponentName(context, DetailActivity.class),
null
);
Filter dapat menyertakan tindakan intent (parameter ketiga) untuk peluncuran aktivitas sekunder. Jika Anda menyertakan tindakan intent, filter tersebut akan memeriksa tindakan tersebut bersama dengan nama aktivitasnya. Untuk aktivitas di aplikasi Anda sendiri, Anda mungkin tidak akan memfilter tindakan intent, sehingga argumennya bisa null.
- Tambahkan filter ke kumpulan filter:
SplitManager.kt / createSplit()
val filterSet = setOf(splitPairFilter)
SplitManager.java / createSplit()
Set<SplitPairFilter> filterSet = new HashSet<>();
filterSet.add(splitPairFilter);
- Buat atribut tata letak untuk pemisahan:
SplitManager.kt / createSplit()
val splitAttributes: SplitAttributes = SplitAttributes.Builder()
.setSplitType(SplitAttributes.SplitType.ratio(0.33f))
.setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
.build()
SplitManager.java / createSplit()
SplitAttributes splitAttributes = new SplitAttributes.Builder()
.setSplitType(SplitAttributes.SplitType.ratio(0.33f))
.setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
.build();
SplitAttributes.Builder
membuat objek yang berisi atribut tata letak:
setSplitType
: Menentukan cara area tampilan yang tersedia dialokasikan ke setiap penampung aktivitas. Jenis pemisahan rasio menentukan proporsi tampilan yang ditempati oleh penampung utama; penampung sekunder menempati area tampilan yang tersisa.setLayoutDirection
: Menentukan cara penampung aktivitas disusun relatif terhadap satu sama lain, penampung utama terlebih dahulu.
- Buat aturan pasangan pemisahan:
SplitManager.kt / createSplit()
val splitPairRule = SplitPairRule.Builder(filterSet)
.setDefaultSplitAttributes(splitAttributes)
.setMinWidthDp(840)
.setMinSmallestWidthDp(600)
.setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER)
.setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS)
.setClearTop(false)
.build()
SplitManager.java / createSplit()
SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet)
.setDefaultSplitAttributes(splitAttributes)
.setMinWidthDp(840)
.setMinSmallestWidthDp(600)
.setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER)
.setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS)
.setClearTop(false)
.build();
SplitPairRule.Builder
membuat dan mengonfigurasi aturan:
filterSet
: Berisi filter pasangan pemisahan yang menentukan kapan aturan diterapkan dengan mengidentifikasi aktivitas yang memiliki pemisahan yang sama. Dalam aplikasi contoh,ListActivity
danDetailActivity
ditentukan dalam filter pasangan pemisahan (lihat langkah sebelumnya).setDefaultSplitAttributes
: Menerapkan atribut tata letak ke aturan.setMinWidthDp
: Menetapkan lebar tampilan minimum (dalam piksel yang tidak bergantung kepadatan, dp) yang memungkinkan pemisahan.setMinSmallestWidthDp
: Menetapkan nilai minimum (dalam dp) yang harus diikuti oleh ukuran yang lebih kecil dari dua dimensi tampilan, terlepas dari orientasi perangkat.setFinishPrimaryWithSecondary
: Menetapkan bagaimana menyelesaikan semua aktivitas di penampung sekunder dapat memengaruhi aktivitas di penampung utama.NEVER
menunjukkan sistem tidak boleh menyelesaikan aktivitas utama jika semua aktivitas dalam penampung sekunder selesai. (Lihat Menyelesaikan aktivitas.)setFinishSecondaryWithPrimary
: Menetapkan bagaimana menyelesaikan semua aktivitas di penampung utama dapat memengaruhi aktivitas di penampung sekunder.ALWAYS
menunjukkan bahwa sistem harus selalu menyelesaikan aktivitas dalam penampung sekunder ketika semua aktivitas dalam penampung utama diselesaikan. (Lihat Menyelesaikan aktivitas.)setClearTop
: Menentukan apakah semua aktivitas di penampung sekunder selesai saat aktivitas baru diluncurkan di penampung. False menentukan bahwa aktivitas baru ditumpuk di atas aktivitas yang sudah ada di penampung sekunder.
- Dapatkan instance singleton WindowManager
RuleController
dan tambahkan aturan:
SplitManager.kt / createSplit()
val ruleController = RuleController.getInstance(context)
ruleController.addRule(splitPairRule)
SplitManager.java / createSplit()
RuleController ruleController = RuleController.getInstance(context);
ruleController.addRule(splitPairRule);
Membuat aturan placeholder
API yang diperlukan:
SplitPlaceholderRule
menentukan aturan untuk aktivitas yang menempati penampung sekunder jika tidak ada konten yang tersedia untuk penampung tersebut. Untuk membuat aktivitas placeholder, lihat "Membuat aktivitas placeholder" di bagian "Konfigurasi XML" di codelab ini. (Untuk mengetahui informasi selengkapnya, lihat Placeholder di panduan developer Penyematan aktivitas.)
SplitPlaceholderRule.Builder
membuat SplitPlaceholderRule
. Builder mengambil kumpulan objek ActivityFilter
sebagai argumen. Objek ini menentukan aktivitas yang terkait dengan aturan placeholder. Jika filter cocok dengan aktivitas yang dimulai, sistem menerapkan aturan placeholder.
Anda mendaftarkan aturan dengan komponen RuleController
.
Untuk membuat aturan placeholder terpisah, lakukan hal berikut:
- Buat
ActivityFilter
:
SplitManager.kt / createSplit()
val placeholderActivityFilter = ActivityFilter(
ComponentName(context, ListActivity::class.java),
null
)
SplitManager.java / createSplit()
ActivityFilter placeholderActivityFilter = new ActivityFilter(
new ComponentName(context, ListActivity.class),
null
);
Filter mengaitkan aturan dengan aktivitas utama aplikasi contoh, ListActivity
. Jadi, jika tidak ada konten detail yang tersedia di tata letak daftar-detail, placeholder akan mengisi area detail.
Filter dapat mencakup tindakan intent (parameter kedua) untuk peluncuran aktivitas terkait (peluncuran ListActivity
). Jika Anda menyertakan tindakan intent, filter tersebut akan memeriksa tindakan tersebut bersama dengan nama aktivitasnya. Untuk aktivitas di aplikasi Anda sendiri, Anda mungkin tidak akan memfilter tindakan intent, sehingga argumennya bisa null.
- Tambahkan filter ke kumpulan filter:
SplitManager.kt / createSplit()
val placeholderActivityFilterSet = setOf(placeholderActivityFilter)
SplitManager.java / createSplit()
Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>();
placeholderActivityFilterSet.add(placeholderActivityFilter);
- Buat
SplitPlaceholderRule
:
SplitManager.kt / createSplit()
val splitPlaceholderRule = SplitPlaceholderRule.Builder(
placeholderActivityFilterSet,
Intent(context, PlaceholderActivity::class.java)
).setDefaultSplitAttributes(splitAttributes)
.setMinWidthDp(840)
.setMinSmallestWidthDp(600)
.setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS)
.build()
SplitManager.java / createSplit()
SplitPlaceholderRule splitPlaceholderRule = new SplitPlaceholderRule.Builder(
placeholderActivityFilterSet,
new Intent(context, PlaceholderActivity.class)
).setDefaultSplitAttributes(splitAttributes)
.setMinWidthDp(840)
.setMinSmallestWidthDp(600)
.setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS)
.build();
SplitPlaceholderRule.Builder
membuat dan mengonfigurasi aturan:
placeholderActivityFilterSet
: Berisi filter aktivitas yang menentukan kapan aturan diterapkan dengan mengidentifikasi aktivitas yang terkait dengan aktivitas placeholder.Intent
: Menentukan peluncuran aktivitas placeholder.setDefaultSplitAttributes
: Menerapkan atribut tata letak ke aturan.setMinWidthDp
: Menetapkan lebar tampilan minimum (dalam piksel yang tidak bergantung kepadatan, dp) yang memungkinkan pemisahan.setMinSmallestWidthDp
: Menetapkan nilai minimum (dalam dp) yang harus diikuti oleh ukuran yang lebih kecil dari dua dimensi tampilan, terlepas dari orientasi perangkat.setFinishPrimaryWithPlaceholder
: Menetapkan pengaruh penyelesaian aktivitas placeholder pada aktivitas di penampung utama.ALWAYS
menunjukkan bahwa sistem harus selalu menyelesaikan aktivitas dalam penampung utama saat placeholder selesai. (Lihat Menyelesaikan aktivitas.)
- Tambahkan aturan ke WindowManager
RuleController
:
SplitManager.kt / createSplit()
ruleController.addRule(splitPlaceholderRule)
SplitManager.java / createSplit()
ruleController.addRule(splitPlaceholderRule);
Membuat aturan aktivitas
API yang diperlukan:
ActivityRule
dapat digunakan untuk menentukan aturan untuk aktivitas yang menempati seluruh jendela tugas, seperti dialog modal. (Untuk mengetahui informasi selengkapnya, lihat Modal jendela penuh di panduan developer Penyematan aktivitas.
SplitPlaceholderRule.Builder
membuat SplitPlaceholderRule
. Builder mengambil kumpulan objek ActivityFilter
sebagai argumen. Objek ini menentukan aktivitas yang terkait dengan aturan placeholder. Jika filter cocok dengan aktivitas yang dimulai, sistem menerapkan aturan placeholder.
Anda mendaftarkan aturan dengan komponen RuleController
.
Untuk membuat aturan aktivitas, lakukan langkah berikut:
- Buat
ActivityFilter
:
SplitManager.kt / createSplit()
val summaryActivityFilter = ActivityFilter(
ComponentName(context, SummaryActivity::class.java),
null
)
SplitManager.java / createSplit()
ActivityFilter summaryActivityFilter = new ActivityFilter(
new ComponentName(context, SummaryActivity.class),
null
);
Filter menentukan aktivitas tempat aturan diterapkan, SummaryActivity
.
Filter dapat mencakup tindakan intent (parameter kedua) untuk peluncuran aktivitas terkait (peluncuran SummaryActivity
). Jika Anda menyertakan tindakan intent, filter tersebut akan memeriksa tindakan tersebut bersama dengan nama aktivitasnya. Untuk aktivitas di aplikasi Anda sendiri, Anda mungkin tidak akan memfilter tindakan intent, sehingga argumennya bisa null.
- Tambahkan filter ke kumpulan filter:
SplitManager.kt / createSplit()
val summaryActivityFilterSet = setOf(summaryActivityFilter)
SplitManager.java / createSplit()
Set<ActivityFilter> summaryActivityFilterSet = new HashSet<>();
summaryActivityFilterSet.add(summaryActivityFilter);
- Buat
ActivityRule
:
SplitManager.kt / createSplit()
val activityRule = ActivityRule.Builder(summaryActivityFilterSet)
.setAlwaysExpand(true)
.build()
SplitManager.java / createSplit()
ActivityRule activityRule = new ActivityRule.Builder(
summaryActivityFilterSet
).setAlwaysExpand(true)
.build();
ActivityRule.Builder
membuat dan mengonfigurasi aturan:
summaryActivityFilterSet
: Berisi filter aktivitas yang menentukan kapan aturan diterapkan dengan mengidentifikasi aktivitas yang ingin Anda kecualikan dari pemisahan.setAlwaysExpand
: Menetapkan apakah aktivitas harus diperluas atau tidak untuk mengisi semua ruang tampilan yang tersedia.
- Tambahkan aturan ke WindowManager
RuleController
:
SplitManager.kt / createSplit()
ruleController.addRule(activityRule)
SplitManager.java / createSplit()
ruleController.addRule(activityRule);
Menjalankan aplikasi
Build dan jalankan aplikasi contoh.
Aplikasi harus berperilaku sama seperti ketika disesuaikan menggunakan file konfigurasi XML.
Lihat "Menjalankan aplikasi" di bagian "Konfigurasi XML" di codelab ini.
Kredit ekstra
Coba tetapkan rasio aspek di aplikasi contoh menggunakan metode setMaxAspectRatioInPortrait
dan setMaxAspectRatioInLandscape
dari SplitPairRule.Builder
dan SplitPlaceholderRule.Builder
. Tentukan nilai dengan properti dan metode class EmbeddingAspectRatio
, misalnya:
SplitPairRule.Builder(filterSet)
. . .
.setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
. . .
.build()
Uji setelan dengan tablet besar atau emulator Pixel C Anda.
Tentukan rasio aspek potret dari tablet besar Anda (rasio aspek Pixel C sedikit lebih besar dari 1,4). Tetapkan rasio aspek maksimum dalam mode potret ke nilai yang lebih tinggi dan lebih rendah daripada rasio aspek tablet atau Pixel C Anda. Coba properti ALWAYS_ALLOW
dan ALWAYS_DISALLOW
.
Jalankan aplikasi, dan lihat hasil yang Anda dapatkan.
Untuk mengetahui informasi selengkapnya, lihat "Rasio aspek" di bagian "Konfigurasi XML" di codelab ini.
7. Navigasi Desain Material
Pedoman Desain Material menentukan komponen navigasi yang berbeda untuk ukuran layar yang berbeda—kolom samping navigasi untuk layar yang lebih lebar atau sama dengan 840dp, menu navigasi bawah untuk layar yang kurang dari 840dp.
Dengan penyematan aktivitas, Anda tidak dapat menggunakan metode WindowManager
getCurrentWindowMetrics()
dan getMaximumWindowMetrics()
untuk menentukan lebar layar karena metrik jendela yang ditampilkan oleh metode menjelaskan panel tampilan yang berisi aktivitas tersemat yang memanggil metode.
Untuk mendapatkan dimensi yang akurat dari aplikasi penyematan aktivitas Anda, gunakan kalkulator atribut pemisahan dan SplitAttributesCalculatorParams.
Hapus baris berikut jika Anda menambahkannya di bagian sebelumnya.
main_split_config.xml
<SplitPairRule
. . .
window:splitMaxAspectRatioInPortrait="alwaysAllow" // Delete this line.
window:splitMaxAspectRatioInLandscape="alwaysDisallow" // Delete this line.
. . .>
</SplitPairRule>
<SplitPlaceholderRule
. . .
window:splitMaxAspectRatioInPortrait="alwaysAllow" // Delete this line.
window:splitMaxAspectRatioInLandscape="alwaysDisallow" // Delete this line.
. . .>
<SplitPlaceholderRule/>
Navigasi yang fleksibel
Untuk mengganti komponen navigasi secara dinamis berdasarkan ukuran layar, gunakan kalkulator SplitAttributes
. Kalkulator mendeteksi perubahan orientasi perangkat dan ukuran jendela serta menghitung ulang dimensi tampilan dengan tepat. Kami akan mengintegrasikan kalkulator dengan SplitController
untuk memicu perubahan komponen navigasi sebagai respons terhadap pembaruan ukuran layar.
Membuat tata letak navigasi
Pertama, buat menu yang akan kita gunakan untuk mengisi kolom samping navigasi dan menu navigasi.
Di folder res/menu
, buat file resource menu baru bernama nav_menu.xml
. Ganti konten file menu dengan berikut ini:
nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:title="Home" />
<item
android:id="@+id/navigation_dashboard"
android:title="Dashboard" />
<item
android:id="@+id/navigation_settings"
android:title="Settings" />
</menu>
Selanjutnya, tambahkan menu navigasi dan kolom samping navigasi ke tata letak Anda. Atur visibilitasnya ke gone
agar tersembunyi pada awalnya. Kita akan membuatnya terlihat nanti berdasarkan dimensi tata letak.
activity_list.xml
<com.google.android.material.navigationrail.NavigationRailView
android:id="@+id/navigationRailView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/nav_menu"
android:visibility="gone" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:menu="@menu/nav_menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone" />
Tulis fungsi untuk menangani peralihan antara menu navigasi dan kolom samping navigasi.
ListActivity.kt / setWiderScreenNavigation()
private fun setWiderScreenNavigation(useNavRail: Boolean) {
val navRail = findViewById(R.id.navigationRailView)
val bottomNav = findViewById(R.id.bottomNavigationView)
if (useNavRail) {
navRail.visibility = View.VISIBLE
bottomNav.visibility = View.GONE
} else {
navRail.visibility = View.GONE
bottomNav.visibility = View.VISIBLE
}
}
ListActivity.java / setWiderScreenNavigation()
private void setWiderScreenNavigation(boolean useNavRail) {
NavigationRailView navRail = findViewById(R.id.navigationRailView);
BottomNavigationView bottomNav = findViewById(R.id.bottomNavigationView);
if (useNavRail) {
navRail.setVisibility(View.VISIBLE);
bottomNav.setVisibility(View.GONE);
} else {
navRail.setVisibility(View.GONE);
bottomNav.setVisibility(View.VISIBLE);
}
}
Kalkulator atribut pemisahan
SplitController
mendapatkan informasi tentang pemisahan aktivitas yang sedang aktif dan memberikan titik interaksi untuk menyesuaikan pemisahan serta membentuk pemisahan baru.
Di bagian sebelumnya, kita telah menetapkan atribut default untuk pemisahan dengan menentukan splitRatio
dan atribut lainnya di tag <SplitPairRule>
dan <SplitPlaceHolderRule>
dalam file XML atau dengan menggunakan API SplitPairRule.Builder#setDefaultSplitAttributes()
dan SplitPlaceholderRule.Builder#setDefaultSplitAttributes()
.
Atribut pemisahan default diterapkan jika WindowMetrics penampung induk memenuhi persyaratan dimensi SplitRule, yaitu minWidthDp, minHeightDp, dan minSmallestWidthDp.
Kita akan menetapkan kalkulator atribut pemisahan untuk menggantikan atribut pemisahan default. Kalkulator memperbarui pasangan pemisahan yang ada setelah perubahan pada jendela atau status perangkat, seperti perubahan orientasi atau perubahan status perangkat foldable.
Hal ini memungkinkan developer mempelajari status perangkat atau jendela dan menetapkan atribut pemisahan yang berbeda dalam skenario yang berbeda, termasuk orientasi potret dan lanskap serta postur mode di atas meja.
Saat membuat kalkulator atribut pemisahan, platform meneruskan objek SplitAttributesCalculatorParams
ke fungsi setSplitAttributesCalculator()
. Properti parentWindowMetrics
menyediakan metrik jendela aplikasi.
Pada kode berikut, aktivitas memeriksa apakah batasan default terpenuhi, yaitu lebar > 840dp dan lebar terkecil > 600dp. Jika kondisi ini terpenuhi, aktivitas akan disematkan dalam tata letak panel ganda, dan aplikasi menggunakan kolom samping navigasi, bukan menu navigasi bawah. Jika tidak, aktivitas akan ditampilkan dalam layar penuh dengan menu navigasi bawah.
ListActivity.kt / setSplitAttributesCalculator()
SplitController.getInstance(this).setSplitAttributesCalculator
params ->
if (params.areDefaultConstraintsSatisfied) {
// When default constraints are satisfied, use the navigation rail.
setWiderScreenNavigation(true)
return@setSplitAttributesCalculator params.defaultSplitAttributes
} else {
// Use the bottom navigation bar in other cases.
setWiderScreenNavigation(false)
// Expand containers if the device is in portrait or the width is less than 840 dp.
SplitAttributes.Builder()
.setSplitType(SPLIT_TYPE_EXPAND)
.build()
}
}
ListActivity.java / setSplitAttributesCalculator()
SplitController.getInstance(this).setSplitAttributesCalculator(params -> {
if (params.areDefaultConstraintsSatisfied()) {
// When default constraints are satisfied, use the navigation rail.
setWiderScreenNavigation(true);
return params.getDefaultSplitAttributes();
} else {
// Use the bottom navigation bar in other cases.
setWiderScreenNavigation(false);
// Expand containers if the device is in portrait or the width is less than 600 dp.
return new SplitAttributes.Builder()
.setSplitType(SplitType.SPLIT_TYPE_EXPAND)
.build();
}
});
Kerja bagus, aplikasi penyematan aktivitas Anda kini telah mengikuti pedoman navigasi Desain Material.
8. Selamat!
Bagus! Anda telah mengoptimalkan aplikasi berbasis aktivitas ke tata letak daftar-detail di layar besar dan menambahkan navigasi Desain Material.
Anda telah mempelajari dua cara untuk menerapkan penyematan aktivitas:
- Menggunakan file konfigurasi XML
- Melakukan panggilan Jetpack API
- Menerapkan navigasi yang fleksibel dengan Penyematan Aktivitas
Anda juga tidak menulis ulang kode sumber Kotlin atau Java apa pun.
Anda siap untuk mengoptimalkan aplikasi produksi untuk perangkat layar besar dengan penyematan aktivitas.
9. Pelajari lebih lanjut
- Panduan developer — Penyematan aktivitas
- Dokumentasi referensi — androidx.window.embedding