Uygulama yönünü telefonlarda kısıtlayın ancak büyük ekranlı cihazlarda kısıtlama uygulamayın

Uygulamanız dikey yönde çalışan telefonlarda mükemmel çalışıyor. Bu nedenle uygulamayı yalnızca dikey olarak kullanmaya karar verdiniz. Ancak yatay yönde büyük ekranlarda daha fazlasını yapma fırsatı görürsünüz.

Uygulamayı küçük ekranlarda dikey yönde, büyük ekranlarda ise yatay yönde göstermek için ne yapabilirsiniz?

Bu kılavuz, uygulamanızı tüm cihaz yapılandırmaları için tam destek sağlayacak şekilde iyileştirene kadar geçici bir önlemdir.

Uygulama yönünü yönetme

Büyük ekranlarda yatay yönü etkinleştirmek için uygulama manifest'inizi, yön değişikliklerini varsayılan olarak ele alacak şekilde ayarlayın. Çalışma zamanında uygulama penceresi boyutunu belirleyin. Uygulama penceresi küçükse manifest yön ayarını geçersiz kılarak uygulamanın yönünü kısıtlayın.

1. Uygulama manifestinde yön ayarını belirtme

Uygulama manifest dosyasının screenOrientation öğesini belirtmemeyi tercih edebilirsiniz (bu durumda yön varsayılan olarak unspecified olur) veya ekran yönünü fullUser olarak ayarlayabilirsiniz. Kullanıcı sensör tabanlı döndürmeyi kilitlemediyse uygulamanız tüm cihaz yönlerini destekler.

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

unspecified ile fullUser arasındaki fark küçük olsa da önemlidir. screenOrientation değeri belirtmezseniz sistem yönü seçer ve sistemin yönü tanımlamak için kullandığı politika cihazdan cihaza farklılık gösterebilir. Öte yandan, fullUser değerini belirtmek, kullanıcının cihaz için tanımladığı davranışla daha uyumludur: Kullanıcı, sensör tabanlı döndürmeyi kilitlediyse uygulama kullanıcı tercihini izler. Aksi takdirde sistem, dört olası ekran yöneliminden herhangi birine (dikey, yatay, ters dikey veya ters yatay) izin verir. screenOrientation adresine göz atın.

2. Ekran boyutunu belirleme

Kullanıcı tarafından izin verilen tüm yönleri desteklemek üzere ayarlanan manifest ile uygulama yönünü ekran boyutuna göre programatik olarak belirtebilirsiniz.

Jetpack WindowManager kitaplıklarını modülün build.gradle veya build.gradle.kts dosyasına ekleyin:

Kotlin

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

Groovy

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

Cihaz ekran boyutunu WindowMetrics nesnesi olarak almak için Jetpack WindowManager WindowMetricsCalculator#computeMaximumWindowMetrics() yöntemini kullanın. Yönlendirmenin ne zaman kısıtlanacağına karar vermek için pencere metrikleri, pencere boyutu sınıflarıyla karşılaştırılabilir.

Windows boyutu sınıfları, küçük ve büyük ekranlar arasındaki kesme noktalarını sağlar.

Ekran boyutunu belirlemek için WindowWidthSizeClass#COMPACT ve WindowHeightSizeClass#COMPACT kesme noktalarını kullanın:

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;
}
    Not:
  • Örnekler bir etkinliğin yöntemleri olarak uygulanır. Bu nedenle, etkinlik, computeMaximumWindowMetrics() bağımsız değişkeninde this olarak başvuru alır.
  • Uygulama, ekran yönü ayarını yok sayan çoklu pencere modunda başlatılabileceğinden computeCurrentWindowMetrics() yerine computeMaximumWindowMetrics() yöntemi kullanılır. Uygulama penceresi cihaz ekranının tamamı olmadığı sürece uygulama penceresi boyutunu belirlemenin ve yön ayarını geçersiz kılmanın bir anlamı yoktur.

computeMaximumWindowMetrics() yöntemini uygulamanızda kullanılabilir hale getirmek için bağımlılıkları beyan etmeyle ilgili talimatlar için WindowManager'a bakın.

3. Uygulama manifesti ayarını geçersiz kılma

Cihazın kompakt ekran boyutuna sahip olduğunu belirlediğinizde manifest'in screenOrientation ayarını geçersiz kılmak için Activity#setRequestedOrientation() işlevini çağırabilirsiniz:

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);
            }
        }
    });
}

onCreate() ve View.onConfigurationChanged() yöntemlerine mantık ekleyerek, cihaz döndürüldükten sonra veya katlanabilir bir cihaz katlandığında ya da açıldığında olduğu gibi etkinlik yeniden boyutlandırıldığında ya da ekranlar arasında taşındığında maksimum pencere metriklerini elde edebilir ve yön ayarını geçersiz kılabilirsiniz. Yapılandırma değişikliklerinin ne zaman gerçekleştiği ve ne zaman etkinlik yeniden oluşturulmasına neden olduğu hakkında daha fazla bilgi için Yapılandırma değişikliklerini yönetme başlıklı makaleyi inceleyin.

Önemli noktalar

  • screenOrientation: Uygulamanızın cihaz yönü değişikliklerine nasıl yanıt vereceğini belirtmenizi sağlayan uygulama manifesti ayarı
  • Jetpack WindowManager: Uygulama penceresinin boyutunu ve en boy oranını belirlemenizi sağlayan kitaplık grubu; API düzeyi 14 ile geriye dönük uyumludur
  • Activity#setRequestedOrientation(): Uygulama yönünü çalışma zamanında değiştirebileceğiniz yöntem

Sonuçlar

Uygulamanız artık cihazın döndürülmesine bakılmaksızın küçük ekranlarda dikey yönde kalır. Uygulama, büyük ekranlarda yatay ve dikey yönleri desteklemelidir.

Bu kılavuzu içeren koleksiyonlar

Bu kılavuz, daha geniş Android geliştirme hedeflerini kapsayan, özel olarak seçilmiş Hızlı Kılavuz koleksiyonlarının bir parçasıdır:

Uygulamanızın tabletler, katlanabilir cihazlar ve ChromeOS cihazlarda optimize edilmiş bir kullanıcı deneyimi sunmasını sağlayın.

Sorularınız veya geri bildiriminiz mi var?

Sık sorulan sorular sayfamıza giderek kısa kılavuzlar hakkında bilgi edinebilir veya bize ulaşarak düşüncelerinizi bizimle paylaşabilirsiniz.