Uygulamanızın kullanıma sunulmasını sağlayın

Katlanmamış büyük ekranlar ve benzersiz katlanmış durum özellikleri, katlanabilir cihazlarda yeni kullanıcı deneyimleri yaşamanızı sağlar. Uygulamanızı katlama özelliğine uygun hale getirmek için, katlama ve menteşe gibi katlanabilir cihaz pencere özellikleri için bir API yüzeyi sağlayan Jetpack WindowManager kitaplığını kullanın. Uygulamanız katlama özelliğine duyarlı olduğunda düzenini uyarlayarak önemli içeriklerin kıvrım veya menteşe alanına yerleştirilmemesine ve doğal ayırıcılar olarak kıvrım ve menteşelerin kullanılmasından kaçınabilir.

Pencere bilgileri

Jetpack WindowManager'daki WindowInfoTracker arayüzü, pencere düzeni bilgilerini gösterir. Arayüzün windowLayoutInfo() yöntemi, uygulamanızı katlanabilir cihazların katlama durumu hakkında bilgilendiren bir WindowLayoutInfo veri akışı döndürür. WindowInfoTracker getOrCreate() yöntemi, WindowInfoTracker öğesinin bir örneğini oluşturur.

WindowManager Kotlin Akışları ve Java geri çağırmalarını kullanarak WindowLayoutInfo verilerinin toplanması için destek sunar.

Kotlin Akışları

WindowLayoutInfo veri toplama işlemini başlatmak ve durdurmak için yeniden başlatılabilir, yaşam döngüsüne duyarlı bir eş yordam kullanabilirsiniz. Bu örnekte, yaşam döngüsü en az STARTED olduğunda repeatOnLifecycle kod bloğu yürütülür ve yaşam döngüsü STOPPED olduğunda durdurulur. Yaşam döngüsü tekrar STARTED olduğunda kod bloğunun yürütülmesi otomatik olarak yeniden başlatılır. Aşağıdaki örnekte kod bloğu WindowLayoutInfo verilerini toplar ve kullanır:

class DisplayFeaturesActivity : AppCompatActivity() {

    private lateinit var binding: ActivityDisplayFeaturesBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityDisplayFeaturesBinding.inflate(layoutInflater)
        setContentView(binding.root)

        lifecycleScope.launch(Dispatchers.Main) {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                WindowInfoTracker.getOrCreate(this@DisplayFeaturesActivity)
                    .windowLayoutInfo(this@DisplayFeaturesActivity)
                    .collect { newLayoutInfo ->
                        // Use newLayoutInfo to update the layout.
                    }
            }
        }
    }
}

Java geri çağırmaları

androidx.window:window-java bağımlılığına dahil edilen geri çağırma uyumluluk katmanı, Kotlin Akışı kullanmadan WindowLayoutInfo güncellemelerini toplayabilmenizi sağlar. Bu yapı, WindowLayoutInfo güncellemelerini almak için geri çağırmaları (ve kaydın iptalini) desteklemek üzere WindowInfoTracker'ı uyarlayan WindowInfoTrackerCallbackAdapter sınıfını içerir. Örneğin:

public class SplitLayoutActivity extends AppCompatActivity {

    private WindowInfoTrackerCallbackAdapter windowInfoTracker;
    private ActivitySplitLayoutBinding binding;
    private final LayoutStateChangeCallback layoutStateChangeCallback =
            new LayoutStateChangeCallback();

   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
       setContentView(binding.getRoot());

       windowInfoTracker =
                new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
   }

   @Override
   protected void onStart() {
       super.onStart();
       windowInfoTracker.addWindowLayoutInfoListener(
                this, Runnable::run, layoutStateChangeCallback);
   }

   @Override
   protected void onStop() {
       super.onStop();
       windowInfoTracker
           .removeWindowLayoutInfoListener(layoutStateChangeCallback);
   }

   class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
       @Override
       public void accept(WindowLayoutInfo newLayoutInfo) {
           SplitLayoutActivity.this.runOnUiThread( () -> {
               // Use newLayoutInfo to update the layout.
           });
       }
   }
}

RxJava desteği

Zaten RxJava (2 veya 3 sürümü) kullanıyorsanız Kotlin Akışı kullanmadan WindowLayoutInfo güncellemeleri toplamak için Observable veya Flowable sunan yapılardan yararlanabilirsiniz.

androidx.window:window-rxjava2 ve androidx.window:window-rxjava3 bağımlılıkları tarafından sağlanan uyumluluk katmanı, uygulamanızın WindowLayoutInfo güncellemelerini almasını sağlayan WindowInfoTracker#windowLayoutInfoFlowable() ve WindowInfoTracker#windowLayoutInfoObservable() yöntemlerini içerir. Örneğin:

class RxActivity: AppCompatActivity {

    private lateinit var binding: ActivityRxBinding

    private var disposable: Disposable? = null
    private lateinit var observable: Observable<WindowLayoutInfo>

   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
       setContentView(binding.getRoot());

        // Create a new observable
        observable = WindowInfoTracker.getOrCreate(this@RxActivity)
            .windowLayoutInfoObservable(this@RxActivity)
   }

   @Override
   protected void onStart() {
       super.onStart();

        // Subscribe to receive WindowLayoutInfo updates
        disposable?.dispose()
        disposable = observable
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { newLayoutInfo ->
            // Use newLayoutInfo to update the layout
        }
   }

   @Override
   protected void onStop() {
       super.onStop();

        // Dispose the WindowLayoutInfo observable
        disposable?.dispose()
   }
}

Katlanabilir ekranların özellikleri

WindowLayoutInfo Jetpack WindowManager sınıfı, görüntüleme penceresinin özelliklerini DisplayFeature öğeleri listesi olarak kullanılabilir hale getirir.

FoldingFeature, aşağıdakiler de dahil olmak üzere katlanabilir ekranlar hakkında bilgi sağlayan bir DisplayFeature türüdür:

  • state: Cihazın katlanmış durumu (FLAT veya HALF_OPENED)
  • orientation: Katlamanın veya menteşenin yönü, HORIZONTAL ya da VERTICAL
  • occlusionType: Katlama veya menteşenin ekranın bir kısmını gizleyip gizlemediği (NONE veya FULL)
  • isSeparating: Katlamanın veya menteşenin iki mantıksal görüntüleme alanı oluşturup oluşturmadığı (doğru ve yanlış)

HALF_OPENED olan katlanabilir cihazlar, ekran iki görüntüleme alanına ayrıldığından her zaman isSeparating değerini "doğru" olarak bildirir. Ayrıca, uygulama her iki ekranı da kapsıyorsa çift ekranlı cihazlarda isSeparating her zaman doğrudur.

FoldingFeature bounds özelliği (DisplayFeature kaynağından devralınmıştır), katlama veya menteşe gibi bir katlama özelliğinin sınırlayıcı dikdörtgenini temsil eder. Sınırlar, ekrandaki öğeleri özelliğe göre konumlandırmak için kullanılabilir.

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    lifecycleScope.launch(Dispatchers.Main) {
        lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
            // Safely collects from windowInfoRepo when the lifecycle is STARTED
            // and stops collection when the lifecycle is STOPPED
            WindowInfoTracker.getOrCreate(this@MainActivity)
                .windowLayoutInfo(this@MainActivity)
                .collect { layoutInfo ->
                    // New posture information
                    val foldingFeature = layoutInfo.displayFeatures
                        .filterIsInstance()
                        .firstOrNull()
                    // Use information from the foldingFeature object
                }

        }
    }
}

Java

private WindowInfoTrackerCallbackAdapter windowInfoTracker;
private final LayoutStateChangeCallback layoutStateChangeCallback =
                new LayoutStateChangeCallback();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    windowInfoTracker =
            new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
}

@Override
protected void onStart() {
    super.onStart();
    windowInfoTracker.addWindowLayoutInfoListener(
            this, Runnable::run, layoutStateChangeCallback);
}

@Override
protected void onStop() {
    super.onStop();
    windowInfoTracker.removeWindowLayoutInfoListener(layoutStateChangeCallback);
}

class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
    @Override
    public void accept(WindowLayoutInfo newLayoutInfo) {
        // Use newLayoutInfo to update the Layout
        List<DisplayFeature> displayFeatures = newLayoutInfo.getDisplayFeatures();
        for (DisplayFeature feature : displayFeatures) {
            if (feature instanceof FoldingFeature) {
                // Use information from the feature object
            }
        }
    }
}

Masa üstü modu

Uygulamanız, FoldingFeature nesnesindeki bilgileri kullanarak telefonun yüzeyde durduğu, menteşenin yatay konumda olduğu ve katlanabilir ekranın yarı açık olduğu masaüstü modu gibi duruşları destekleyebilir.

Masa üstü modu, kullanıcılara telefonu ellerinde tutmadan telefonlarını kullanma rahatlığı sunar. Masa üstü modu medya izlemek, fotoğraf çekmek ve görüntülü görüşme yapmak için idealdir.

Masaüstü modundaki video oynatıcı uygulaması

Cihazın masaüstü modunda olup olmadığını belirlemek için FoldingFeature.State ve FoldingFeature.Orientation özelliklerini kullanın:

Kotlin


fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean {
    contract { returns(true) implies (foldFeature != null) }
    return foldFeature?.state == FoldingFeature.State.HALF_OPENED &&
            foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
}

Java


boolean isTableTopPosture(FoldingFeature foldFeature) {
    return (foldFeature != null) &&
           (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) &&
           (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL);
}

Cihazın masaüstü modunda olduğunu öğrendikten sonra uygulama düzeninizi uygun şekilde güncelleyin. Medya uygulamaları için bu, genellikle oynatmayı ekranın üst kısmına yerleştirmek ve ellerinizi kullanmadan görüntüleme veya dinleme deneyimi için konumlandırma kontrolleriyle ek içeriğin hemen altına yerleştirilmesi anlamına gelir.

Örnekler

  • MediaPlayerActivity uygulaması: Ekrana katlama duyarlı video oynatıcı oluşturmak için Media3 Exoplayer ve WindowManager'ı nasıl kullanacağınızı öğrenin.

  • Kamera deneyiminizi geliştirin codelab'i: Fotoğraf uygulamaları için masaüstü modunu nasıl uygulayacağınızı öğrenin. Vizörü ekranın üst yarısında, ekranın üst kısmında, kontrolleri ise alt yarısında, ekranın alt kısmında gösterin.

Kitap modu

Bir diğer benzersiz katlanabilir cihaz duruşu ise cihazın yarı açık ve menteşesinin dikey olduğu kitap modudur. Kitap modu e-kitap okumak için idealdir. Ciltli kitap gibi iki sayfalık katlanabilir sayfa düzeniyle kitap modu, gerçek kitap okuma deneyimini yakalar.

Ellerinizi kullanmadan fotoğraf çekerken farklı bir en boy oranı yakalamak isterseniz bu özellik fotoğrafçılık için de kullanılabilir.

Kitap modunu, masaüstü modu için kullanılan tekniklerle uygulayın. Tek fark kodun, katlama özelliğinin yönünün yatay yerine dikey olup olmadığını kontrol etmesidir:

Kotlin

fun isBookPosture(foldFeature : FoldingFeature?) : Boolean {
    contract { returns(true) implies (foldFeature != null) }
    return foldFeature?.state == FoldingFeature.State.HALF_OPENED &&
            foldFeature.orientation == FoldingFeature.Orientation.VERTICAL
}

Java

boolean isBookPosture(FoldingFeature foldFeature) {
    return (foldFeature != null) &&
           (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) &&
           (foldFeature.getOrientation() == FoldingFeature.Orientation.VERTICAL);
}

Pencere boyutu değişiklikleri

Cihaz yapılandırmasında yapılan bir değişiklik nedeniyle bir uygulamanın görüntüleme alanı değişebilir. Örneğin, cihaz katlandığında veya açıldığında, döndürüldüğünde ya da çoklu pencere modunda bir pencere yeniden boyutlandırıldığında değişebilir.

Jetpack WindowManager WindowMetricsCalculator sınıfı, geçerli ve maksimum pencere metriklerini almanızı sağlar. API düzeyi 30'da sunulan WindowMetrics platformu gibi WindowManager WindowMetrics da pencere sınırlarını sağlar ancak API, API düzeyi 14'e kadar geriye dönük uyumludur.

Farklı ekran boyutlarını destekleme başlıklı makalede farklı pencere boyutlarını nasıl destekleyeceğinizi öğrenebilirsiniz.

Ek kaynaklar

Sana Özel

  • Jetpack WindowManager: Jetpack WindowManager kitaplığının nasıl kullanılacağını gösteren örnek
  • Jetcaster: Compose ile masa üstü duruşu uygulama

Codelab uygulamaları