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

Uygulamanız, telefonlarda dikey yönde mükemmel şekilde çalışıyor. Bu nedenle, uygulamayı yalnızca dikey yönle sınırladınız. Ancak büyük ekranlarda yatay yönde daha fazla işlem yapma fırsatı olduğunu düşünüyorsunuz.

Uygulamayı küçük ekranlarda dikey yönle kısıtlayıp büyük ekranlarda yatay yönü nasıl etkinleştirebilirsiniz?

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

Sonuçlar

Uygulamanız, cihaz döndürülse bile küçük ekranlarda dikey yönde kalır. Uygulama, büyük ekranlarda yatay ve dikey yönleri destekler.

Uygulama yönünü yönetme

Büyük ekranlarda yatay yönlendirmeyi etkinleştirmek için uygulama manifestinizi yönlendirme değişikliklerini varsayılan olarak işleyecek ş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 manifestinin screenOrientation öğesini bildirmekten kaçınabilir (bu durumda yön varsayılan olarak unspecified olur) veya ekran yönünü fullUser olarak ayarlayabilirsiniz. Kullanıcı, sensöre dayalı 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 yönü tanımlamak için sistemin kullandığı politika cihazdan cihaza farklılık gösterebilir. Diğer yandan, fullUser belirtmek, kullanıcının cihaz için tanımladığı davranışla daha iyi eşleşir: Kullanıcı, sensöre dayalı döndürmeyi kilitlemişse uygulama, kullanıcı tercihine uyar. Aksi takdirde sistem, dört olası ekran yönünden herhangi birine (dikey, yatay, ters dikey veya ters yatay) izin verir. screenOrientation sayfasına göz atın.

2. Ekran boyutunu belirleme

Manifest, kullanıcı tarafından izin verilen tüm yönleri destekleyecek şekilde ayarlandığında ekran boyutuna göre uygulama yönünü programatik olarak belirleyebilirsiniz.

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 WindowMetricsCalculator#computeMaximumWindowMetrics() nesnesi olarak almak için Jetpack WindowManager WindowMetrics yöntemini kullanın. Yönü kısıtlamaya ne zaman karar verileceğini belirlemek için pencere metrikleri, pencere boyutu sınıflarıyla karşılaştırılabilir.

Pencere 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 referanssızlaştırılır.
  • Uygulama, ekran yönü ayarını yok sayan çoklu pencere modunda başlatılabildiğinden computeCurrentWindowMetrics() yerine computeMaximumWindowMetrics() yöntemi kullanılır. Uygulama penceresi cihaz ekranının tamamını kaplamıyorsa 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 etme talimatları hakkında bilgi edinmek üzere WindowManager'ı inceleyin.

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

Cihazın ekran boyutunun kompakt olduğunu belirlediğinizde, manifestin screenOrientation ayarını geçersiz kılmak için Activity#setRequestedOrientation()'ı ç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 maksimum pencere metriklerini elde edebilir ve etkinlik yeniden boyutlandırıldığında veya ekranlar arasında taşındığında (ör. cihaz döndürüldükten sonra ya da katlanabilir bir cihaz katlandığında veya açıldığında) 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şturmaya neden olduğu hakkında daha fazla bilgi için Yapılandırma değişikliklerini işleme başlıklı makaleyi inceleyin.

Önemli noktalar

  • screenOrientation: Uygulamanızın cihaz yönü değişikliklerine nasıl yanıt vereceğini belirtmenize olanak tanıyan uygulama manifesti ayarı
  • Jetpack WindowManager: Uygulama penceresinin boyutunu ve en-boy oranını belirlemenizi sağlayan kitaplıklar kümesi; 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

Bu kılavuzu içeren koleksiyonlar

Bu kılavuz, daha kapsamlı Android geliştirme hedeflerini ele alan şu derlenmiş Hızlı Kılavuz koleksiyonlarının bir parçasıdır:

Uygulamanızın tabletlerde, katlanabilir cihazlarda ve ChromeOS cihazlarda optimize edilmiş bir kullanıcı deneyimini desteklemesini sağlayın.

Sorularınız veya geri bildiriminiz mi var?

Sık sorulan sorular sayfamıza giderek hızlı kılavuzlar hakkında bilgi edinebilir veya düşüncelerinizi bize iletebilirsiniz.