Membuat aplikasi Anda fold aware

Dengan layar besar yang dibentangkan dan bentuk lipatan unik memungkinkan pengalaman pengguna baru di perangkat foldable. Agar aplikasi Anda menjadi fold aware di Jetpack Compose, gunakan library Compose Material 3 Adaptive, yang menyediakan API untuk fitur jendela perangkat foldable seperti lipatan, engsel, dan postur perangkat. Jika aplikasi Anda fold-aware, aplikasi dapat menyesuaikan tata letaknya untuk menghindari penempatan konten penting di area lipatan atau engsel serta menggunakan lipatan dan engsel sebagai pemisah alami.

Memahami apakah perangkat mendukung konfigurasi seperti mode di atas meja atau postur buku dapat memandu keputusan tentang mendukung tata letak yang berbeda atau menyediakan fitur tertentu.

Informasi jendela

Di Jetpack Compose, gunakan collectFoldingFeaturesAsState() composable fungsi untuk mengamati informasi lipatan jendela. collectFoldingFeaturesAsState() mengumpulkan fitur lipatan jendela saat ini dari WindowInfoTracker ke dalam State Compose yang berisi daftar objek FoldingFeature.

Karena collectFoldingFeaturesAsState() menampilkan State Compose, composable Anda akan otomatis dikomposisi ulang setiap kali status atau postur lipatan perangkat berubah, tanpa memerlukan pengelolaan siklus proses atau pengumpulan aliran secara manual:

@Composable
fun FoldAwareScreen() {
    val foldingFeatures by collectFoldingFeaturesAsState()

    // Access folding features for the current window.
    val foldFeature = foldingFeatures.firstOrNull()
    if (foldFeature != null) {
        // Adapt layout based on the fold feature.
    }
}

Fitur layar perangkat foldable

Daftar elemen FoldingFeature yang ditampilkan oleh collectFoldingFeaturesAsState() (subjenis DisplayFeature) memberikan informasi tentang layar perangkat foldable, termasuk properti berikut:

  • state: Status lipatan perangkat, FLAT atau HALF_OPENED

  • orientation: Orientasi lipatan atau engsel, HORIZONTAL atau VERTICAL

  • occlusionType: Apakah lipatan atau engsel menyembunyikan bagian layar, NONE atau FULL

  • isSeparating: Apakah lipatan atau engsel membuat dua area tampilan logis, benar (true) atau salah (salah)

Perangkat foldable yang HALF_OPENED selalu melaporkan isSeparating sebagai benar (true) karena layar dipisahkan menjadi dua area tampilan. Selain itu, isSeparating selalu bernilai benar (true) pada perangkat dua layar saat aplikasi membentang pada kedua layar.

Properti FoldingFeature bounds (diwarisi dari DisplayFeature) mewakili persegi panjang pembatas fitur lipat seperti lipatan atau engsel. Batas dapat digunakan untuk memosisikan elemen di layar yang terkait dengan fitur:

@Composable
fun FoldFeatureDemo() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    if (foldFeature != null) {
        val isSeparating = foldFeature.isSeparating
        val occlusionType = foldFeature.occlusionType
        val bounds = foldFeature.bounds
        // Use bounds and properties to position content.
    }
}

Postur di atas meja

Dengan menggunakan informasi yang disertakan dalam objek FoldingFeature, aplikasi Anda dapat mendukung postur seperti mode di atas meja, dengan ponsel berada di permukaan, engsel berada dalam posisi horizontal, dan layar perangkat foldable dibuka setengah.

Postur di atas meja menawarkan kenyamanan kepada pengguna dalam mengoperasikan ponsel tanpa memegang ponsel. Postur di atas meja sangat cocok untuk menonton media, mengambil foto, dan melakukan panggilan video.

Aplikasi pemutar video dalam posisi di atas meja dengan pemutaran video di
        bagian vertikal tegak layar dan kontrol pemutaran di
        bagian horizontal bawah.
Gambar 1. Aplikasi pemutar video dalam postur di atas meja—video di bagian vertikal layar; kontrol pemutaran di bagian horizontal.

Gunakan FoldingFeature.State dan FoldingFeature.Orientation dari collectFoldingFeaturesAsState() untuk menentukan apakah perangkat dalam postur di atas meja:

@Composable
fun TabletopContent() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    val isTableTopPosture = foldFeature != null &&
        foldFeature.state == FoldingFeature.State.HALF_OPENED &&
        foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL

    if (isTableTopPosture) {
        // Tabletop layout: separate content and controls across the fold.
    } else {
        // Standard layout.
    }
}

Atau, Anda dapat menentukan apakah jendela dalam postur di atas meja dengan memeriksa properti Posture yang ditampilkan oleh currentWindowAdaptiveInfoV2():

val adaptiveInfo = currentWindowAdaptiveInfoV2()
val isTabletop = adaptiveInfo.windowPosture.isTabletop

Setelah mengetahui bahwa perangkat dalam postur di atas meja, perbarui tata letak aplikasi Anda. Untuk aplikasi media, pembaruan ini biasanya berarti menempatkan pemutaran di paruh atas dan kontrol posisi serta konten tambahan tepat di bawahnya untuk pengalaman menonton atau mendengarkan secara handsfree.

Contoh

Postur buku

Fitur unik lain dari perangkat foldable adalah postur buku, dengan perangkat terbuka setengah dan engsel vertikal. Postur buku sangat cocok untuk membaca e‑book. Dengan tata letak dua halaman pada perangkat foldable layar besar yang dapat dilipat dan terbuka seperti buku, postur buku menciptakan pengalaman membaca buku sungguhan.

Mode ini juga dapat digunakan untuk fotografi jika Anda ingin mengambil rasio aspek yang berbeda sambil mengambil gambar secara handsfree.

Terapkan postur buku dengan teknik yang sama dengan yang digunakan untuk postur di atas meja. Pastikan orientasi fitur lipat adalah vertikal, bukan horizontal:

@Composable
fun BookContent() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    val isBookPosture = foldFeature != null &&
        foldFeature.state == FoldingFeature.State.HALF_OPENED &&
        foldFeature.orientation == FoldingFeature.Orientation.VERTICAL

    if (isBookPosture) {
        // Book posture layout: two-page layout across the vertical fold.
    } else {
        // Standard single-page layout.
    }
}

Perubahan ukuran jendela

Area tampilan aplikasi dapat berubah sebagai akibat dari perubahan konfigurasi perangkat, misalnya, saat perangkat dilipat atau dibentangkan, diputar, atau diubah ukurannya dalam mode multi-aplikasi.

Untuk mengambil class ukuran jendela saat ini dan beradaptasi dengan perubahan ukuran di Jetpack Compose, gunakan fungsi composable currentWindowAdaptiveInfoV2() dari library Compose Material 3 Adaptive. currentWindowAdaptiveInfoV2() menampilkan instance WindowAdaptiveInfo yang menyediakan WindowSizeClass jendela saat ini (dengan dukungan untuk breakpoint besar dan sangat besar secara default), serta windowPosture perangkat:

@Composable
fun AdaptiveApp() {
    val adaptiveInfo = currentWindowAdaptiveInfoV2()
    val windowSizeClass = adaptiveInfo.windowSizeClass

    when {
        windowSizeClass.isWidthAtLeastBreakpoint(
            WIDTH_DP_EXPANDED_LOWER_BOUND
        ) -> {
            // Expanded layout
        }
        windowSizeClass.isWidthAtLeastBreakpoint(
            WIDTH_DP_MEDIUM_LOWER_BOUND
        ) -> {
            // Medium layout
        }
        else -> {
            // Compact layout
        }
    }
}

Lihat Menggunakan class ukuran jendela.

Referensi lainnya

Untuk mempelajari lebih lanjut tata letak fold-aware dan perangkat foldable, lihat referensi berikut:

Contoh

  • Contoh Jetpack WindowManager: Contoh cara menggunakan library Jetpack WindowManager
  • Jetcaster : Implementasi postur di atas meja dengan Compose

Codelab