Jetpack Window Manager untuk perangkat yang dapat dilipat

Jetpack Window Manager menyediakan API standar untuk bekerja dengan semua perangkat yang dapat dilipat. Ini berisi dua kelas penting:

  • DisplayFeature - Mengidentifikasi gangguan di permukaan layar datar berkelanjutan seperti engsel atau lipatan. Window Manager akan mengembalikan kumpulan fitur tampilan dari panggilan balik perubahan tata letak.
  • FoldingFeature - Menyediakan informasi tentang fitur tertentu dari perangkat. Meskipun Surface Duo hanya memiliki satu fitur lipatan, ada kemungkinan perangkat lain mungkin memiliki lebih banyak.

Panduan serupa ada di Android Foldable Codelab. Baca selengkapnya tentang pengembangan untuk foldable di dokumen Android. Contoh oleh tim Android juga tersedia di GitHub. Catatan rilis Jetpack merekam perubahan di Window Manager saat diperbarui.

Tip

Kontrol dan kelas pembantu di pustaka layar ganda Surface Duo berfungsi dengan Window Manager. Ikuti petunjuk untuk menambahkan paket yang benar ke proyek aplikasi Anda.

Untuk menggunakan Window Manager langsung dalam kode Anda, ikuti instruksi di bawah ini:

Tambahkan dependensi

  1. Pastikan Anda memiliki repositori mavenCentral() di file build.gradle tingkat atas:

    allprojects {
        repositories {
            google()
            mavenCentral()
         }
    }
    
  2. compileSdkVersion Pastikan dan targetSdkVersion diatur ke API 31 atau yang lebih baru dalam file build.gradle tingkat modul Anda:

    android { 
        compileSdkVersion 31
    
        defaultConfig { 
            targetSdkVersion 31
        } 
        ... 
    }
    
    
  3. Tambahkan dependensi berikut ke file build.gradle tingkat modul Anda:

    dependencies {
        implementation "androidx.window:window:1.0.0"
        implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
    }
    

Menggunakan Window Manager dalam kode Kotlin Anda

Saat mengakses properti Window Manager di proyek Kotlin Anda, penting untuk menyiapkan alur informasi yang benar. Jika tidak, Anda mungkin menerima terlalu sedikit atau terlalu banyak pembaruan peristiwa, dan performa aplikasi dapat terpengaruh.

Untuk menginisialisasi dan menggunakan WindowInfoTracker objek, ikuti langkah-langkah di bawah ini:

  1. Di kelas MainActivity Anda, buat variabel untuk WindowInfoTracker. Pastikan bahwa import androidx.window.layout.WindowInfoTracker ditambahkan ke bagian atas file.

    class MainActivity : AppCompatActivity() {
        private lateinit var windowInfoTracker: WindowInfoTracker
    
  2. Inisialisasi WindowInfoTracker dalam metode aktivitas onCreate Anda dan siapkan alur untuk mengumpulkan informasi dari windowLayoutInfo properti .

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        // Initialize the window manager
        windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity)
    
        // Set up a flow
        lifecycleScope.launch(Dispatchers.Main) {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                windowInfoTracker.windowLayoutInfo(this@MainActivity)
                    .collect { 
                        // Check FoldingFeature properties here
                    }
            }
        }
    }
    

    Pastikan bahwa impor ini juga ditambahkan ke bagian atas file:

    import androidx.lifecycle.Lifecycle
    import androidx.lifecycle.lifecycleScope
    import androidx.lifecycle.repeatOnLifecycle
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.flow.collect
    import kotlinx.coroutines.launch
    
  3. Tambahkan kode untuk memeriksa WindowLayoutInfo alur untuk properti fitur lipatan. Ketika kode ini dijalankan, aktivitas akan diperbarui dengan postur perangkat saat ini dan menampilkan fitur (jika membentur di lipatan atau engsel).

    Dalam cuplikan kode di bawah ini, aktivitas menampilkan teks yang berbeda berdasarkan properti .FoldingFeature

    Contoh ini memiliki TextView yang disebut layout_change_text yang menunjukkan jenis oklusi dan isSeparating nilai untuk fitur lipatan yang terdeteksi.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity)
    
        lifecycleScope.launch(Dispatchers.Main) {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                windowInfoTracker.windowLayoutInfo(this@MainActivity)
                    .collect { newLayoutInfo ->
                        layout_change_text.text = "No display features detected"
                        for (displayFeature : DisplayFeature in newLayoutInfo.displayFeatures) {
                            if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.NONE) {
                                layout_change_text.text = "App is spanned across a fold, " +
                                    "isSeparating = ${displayFeature.isSeparating}"
                            }
                            if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.FULL) {
                                layout_change_text.text = "App is spanned across a hinge, " +
                                    "isSeparating = ${displayFeature.isSeparating}"
                            }
                        }
                    }
            }
        }
    }
    

Properti fitur lipatan

Kelas WindowLayoutInfo ini memiliki koleksi DisplayFeature item, satu atau beberapa di antaranya bisa menjadi instans kelas FoldingFeature.

Fitur lipatan memiliki properti berikut:

  • bounds - koordinat persegi panjang pembatas fitur lipat
  • occlusionType - jika fitur lipat menyembunyikan konten (FULL atau NONE)
  • orientation - orientasi fitur lipatan (HORIZONTAL atau VERTICAL)
  • state - sudut fitur lipatan (HALF_OPENED atau FLAT)
  • isSeparating - jika fitur lipat memisahkan area tampilan menjadi dua bagian yang berbeda

Anda dapat mengkueri properti ini untuk membuat keputusan tentang cara menyesuaikan tata letak Anda setelah perubahan konfigurasi.

sedang Memisahkan

Saat memutuskan di mana menempatkan kontrol atau berapa banyak panel konten yang akan diperlihatkan, gunakan properti isSeparating . Bidang ini akan memastikan aplikasi Anda memberikan pengalaman pengguna terbaik di semua perangkat yang dapat dilipat:

  • Untuk perangkat layar ganda, ini akan selalu benar ketika aplikasi dibenamkan di seluruh engsel
  • Untuk perangkat lain yang dapat dilipat, ini hanya akan benar ketika statusnya , HALF_OPENEDseperti ketika perangkat berada dalam postur tabletop

isSeparating Gunakan properti untuk memutuskan apakah akan menyesuaikan tata letak UI aplikasi Anda untuk perangkat yang dapat dilipat, atau menggunakan UI default saat tidak ada pemisahan:

private fun updateCurrentLayout(newLayoutInfo: WindowLayoutInfo) {
   for (displayFeature in newLayoutInfo.displayFeatures) {
       val foldFeature = displayFeature as? FoldingFeature
       foldFeature?.let {
           if (it.isSeparating) {
               // The content is separated by the FoldingFeature.
               // Here is where you should adapt your UI.
           } else {
               // The content is not separated.
               // Users can see and interact with your UI properly.
           }
       }
   }
}

Untuk melihat contoh yang lebih uraikan tentang cara menggunakan bidang ini, lihat sampel pemisahan ini.

Google juga menyediakan dokumentasi dan sampel yang terkait dengan properti ini sebagai bagian dari panduan layar besar dan dapat dilipat.

Sampel

Repositori GitHub surface-duo-jetpack-window-manager-samples berisi sejumlah sampel Kotlin yang menunjukkan pola pengalaman pengguna layar ganda yang berbeda yang dibangun menggunakan Jetpack Window Manager dan sistem tampilan tradisional.

Repositori GitHub surface-duo-compose-samples juga memiliki sampel Kotlin layar ganda yang menggunakan Jetpack Window Manager, tetapi dalam sampel ini UI dibangun dengan Jetpack Compose.

Java API

Lihat Posting blog Jetpack Window Manager dengan Java dan sampel Java ini untuk melihat cara mengakses WindowInfoTracker kelas melalui WindowInfoTrackerCallbackAdapter.

Sumber