Membatasi orientasi aplikasi di ponsel, tetapi tidak untuk perangkat layar besar

Aplikasi Anda berfungsi dengan baik pada ponsel dalam orientasi potret, sehingga Anda membatasi aplikasi ke orientasi potret. Namun, Anda melihat peluang untuk melakukan lebih banyak hal pada perangkat layar besar dalam orientasi lanskap.

Bagaimana cara melakukan keduanya—membatasi aplikasi ke orientasi potret di layar kecil, tetapi mengaktifkan orientasi lanskap pada perangkat layar besar?

Panduan ini adalah tindakan sementara hingga Anda dapat meningkatkan kualitas aplikasi untuk memberikan dukungan penuh bagi semua konfigurasi perangkat.

Mengelola orientasi aplikasi

Untuk mengaktifkan orientasi lanskap di perangkat layar besar, tetapkan manifes aplikasi Anda untuk menangani perubahan orientasi secara default. Saat runtime, tentukan ukuran jendela aplikasi. Jika jendela aplikasi kecil, batasi orientasi aplikasi dengan mengganti setelan orientasi manifes.

1. Menentukan setelan orientasi dalam manifes aplikasi

Anda dapat menghindari mendeklarasikan elemen screenOrientation dari manifes aplikasi (jika orientasi default adalah unspecified) atau menyetel orientasi layar ke fullUser. Jika pengguna belum mengunci rotasi berbasis sensor, aplikasi Anda akan mendukung semua orientasi perangkat.

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

Perbedaan antara unspecified dan fullUser kecil, tetapi penting. Jika Anda tidak mendeklarasikan nilai screenOrientation, sistem akan memilih orientasi, dan kebijakan yang digunakan sistem untuk menentukan orientasi mungkin berbeda dari satu perangkat ke perangkat lainnya. Di sisi lain, menentukan fullUser akan lebih cocok dengan perilaku yang ditentukan pengguna untuk perangkat: jika pengguna telah mengunci rotasi berbasis sensor, aplikasi akan mengikuti preferensi pengguna; jika tidak, sistem akan mengizinkan salah satu dari empat orientasi layar yang memungkinkan (potret, lanskap, potret terbalik, atau lanskap terbalik). Lihat screenOrientation.

2. Menentukan ukuran layar

Dengan manifes yang disetel untuk mendukung semua orientasi yang diizinkan pengguna, Anda dapat menentukan orientasi aplikasi secara terprogram berdasarkan ukuran layar.

Tambahkan library Jetpack WindowManager ke file build.gradle atau build.gradle.kts modul:

Kotlin

implementation("androidx.window:window:version")
implementation("androidx.window:window-core:version")

Groovy

implementation 'androidx.window:window:version'
implementation 'androidx.window:window-core:version'

Gunakan metode WindowMetricsCalculator#computeMaximumWindowMetrics() Jetpack WindowManager untuk mendapatkan ukuran layar perangkat sebagai objek WindowMetrics. Metrik jendela dapat dibandingkan dengan class ukuran jendela untuk menentukan kapan harus membatasi orientasi.

Class ukuran jendela menyediakan titik henti sementara antara layar kecil dan besar.

Gunakan titik henti sementara WindowWidthSizeClass#COMPACT dan WindowHeightSizeClass#COMPACT untuk menentukan ukuran layar:

Kotlin

/** Determines whether the device has a compact screen. **/
fun compactScreen() : Boolean {
    val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
    val width = metrics.bounds.width()
    val height = metrics.bounds.height()
    val density = resources.displayMetrics.density
    val windowSizeClass = WindowSizeClass.compute(width/density, height/density)

    return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT ||
        windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT
}

Java

/** Determines whether the device has a compact screen. **/
private boolean compactScreen() {
    WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this);
    int width = metrics.getBounds().width();
    int height = metrics.getBounds().height();
    float density = getResources().getDisplayMetrics().density;
    WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density);
    return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT ||
                windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT;
}
    Catatan:
  • Contoh diimplementasikan sebagai metode aktivitas; sehingga aktivitas tersebut dihilangkan referensinya sebagai this dalam argumen computeMaximumWindowMetrics().
  • Metode computeMaximumWindowMetrics() digunakan sebagai pengganti computeCurrentWindowMetrics() karena aplikasi dapat diluncurkan dalam mode multi-aplikasi, yang mengabaikan setelan orientasi layar. Anda tidak perlu menentukan ukuran jendela aplikasi dan mengganti setelan orientasi, kecuali jika jendela aplikasi adalah keseluruhan layar perangkat.

Lihat WindowManager untuk mengetahui petunjuk tentang mendeklarasikan dependensi agar metode computeMaximumWindowMetrics() tersedia di aplikasi Anda.

3. Mengganti setelan manifes aplikasi

Setelah menentukan bahwa perangkat memiliki ukuran layar yang kecil, Anda dapat memanggil Activity#setRequestedOrientation() untuk mengganti setelan screenOrientation manifes:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestedOrientation = if (compactScreen())
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    val container: ViewGroup = binding.container

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(object : View(this) {
        override fun onConfigurationChanged(newConfig: Configuration?) {
            super.onConfigurationChanged(newConfig)
            requestedOrientation = if (compactScreen())
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
                ActivityInfo.SCREEN_ORIENTATION_FULL_USER
        }
    })
}

Java

@Override
protected void onCreate(Bundle savedInstance) {
    super.onCreate(savedInstanceState);
    if (compactScreen()) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
    }
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    ViewGroup container = binding.container;

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(new View(this) {
        @Override
        protected void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (compactScreen()) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
            }
        }
    });
}

Dengan menambahkan logika ke metode onCreate() dan View.onConfigurationChanged(), Anda dapat memperoleh metrik jendela maksimum dan mengganti setelan orientasi setiap kali aktivitas diubah ukurannya atau dipindahkan di antara tampilan, seperti setelah rotasi perangkat atau saat perangkat foldable dilipat atau dibentangkan. Untuk informasi selengkapnya tentang kapan perubahan konfigurasi terjadi dan kapan perubahan tersebut menyebabkan pembuatan ulang aktivitas, lihat Menangani perubahan konfigurasi.

Poin utama

  • screenOrientation: Setelan manifes aplikasi yang memungkinkan Anda menentukan respons aplikasi terhadap perubahan orientasi perangkat
  • Jetpack WindowManager: Kumpulan library yang memungkinkan Anda menentukan ukuran dan rasio aspek jendela aplikasi; kompatibel dengan versi lama hingga level API 14
  • Activity#setRequestedOrientation(): Metode yang dapat Anda gunakan untuk mengubah orientasi aplikasi saat runtime

Hasil

Aplikasi Anda akan tetap dalam orientasi potret di layar kecil, apa pun rotasi perangkatnya. Pada perangkat layar besar, aplikasi akan mendukung orientasi lanskap dan potret.

Koleksi yang berisi panduan ini

Panduan ini adalah bagian dari koleksi Panduan Cepat pilihan yang membahas tujuan pengembangan Android yang lebih luas:

Aktifkan aplikasi Anda untuk mendukung pengalaman pengguna yang dioptimalkan di tablet, perangkat foldable, dan perangkat ChromeOS.

Ada pertanyaan atau masukan

Buka halaman pertanyaan umum (FAQ) dan pelajari panduan singkat atau hubungi kami dan beri tahu kami pendapat Anda.