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

Büyük açılmış ekranlar ve benzersiz katlanmış durumlar katlanabilir cihazlar. Uygulamanızı katlanabilir hale getirmek için Jetpack WindowManager kitaplığını sunar. Katlanabilir cihaz penceresi özellikleri için API yüzeyi sunar. gibi katlanabilirler. Uygulamanız katlanabilir cihazlara uyumlu olduğunda, önemli içeriklerin katlama veya menteşe alanlarına yerleştirilmesini önlemek için düzenini uyarlayabilir ve katlama ile menteşeleri doğal ayırıcılar olarak kullanabilir.

Bir cihazın masaüstü veya kitap gibi yapılandırmaları destekleyip desteklemediğini anlama farklı düzenlerin desteklenmesi veya belirli özellikler.

Pencere bilgileri

Jetpack WindowManager'daki WindowInfoTracker arayüzü, pencereyi gösteriyor düzen bilgisi ekleyin. Arayüzün windowLayoutInfo() yöntemi, bir Uygulamanızı katlanabilir cihaz hakkında bilgilendiren WindowLayoutInfo veri akışı katlanmış olması gerekir. WindowInfoTracker#getOrCreate() yöntemi, WindowInfoTracker örneği oluşturur.

WindowManager, Kotlin akışları ve Java geri çağırma işlevlerini kullanarak WindowLayoutInfo verilerini toplama desteği sağlar.

Kotlin akışları

WindowLayoutInfo veri toplamayı başlatmak ve durdurmak için, yaşam döngüsü en az STARTED olduğunda repeatOnLifecycle kod bloğunun yürütüldüğü ve yaşam döngüsü STOPPED olduğunda durdurulduğu bir yeniden başlatılabilir yaşam döngüsü bilinçli işleyici kullanabilirsiniz. Kod bloğunun yürütülmesi otomatik olarak yeniden başlatılır yaşam döngüsü tekrar STARTED olduğunda. Aşağıdaki örnekte, kod bloğu WindowLayoutInfo verilerini toplayıp 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ğırma işlevleri

androidx.window:window-java bağımlılığı, Kotlin akışı kullanılmadan WindowLayoutInfo kez güncellenir. Yapı şunları içeriyor: uyarlayan WindowInfoTrackerCallbackAdapter sınıfı WindowInfoTracker WindowLayoutInfo güncellemeleri alın, ö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 kullanıyorsanız (2 veya 3 sürümü) daha verimli bir şekilde kullanabilmenizi sağlayan yapılardan Observable veya Flowable kullanarak WindowLayoutInfo güncellemelerini Kotlin akışı kullanmadan toplayabilirsiniz.

androidx.window:window-rxjava2 ve androidx.window:window-rxjava3 bağımlılıkları tarafından sağlanan uyumluluk katmanı, uygulamanızın WindowLayoutInfo güncellemeleri 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 of the WindowLayoutInfo observable.
        disposable?.dispose()
   }
}

Katlanabilir ekranların özellikleri

Jetpack WindowManager'ın WindowLayoutInfo sınıfı bir görüntüleme penceresi DisplayFeature öğe listesi olarak kullanılabilir.

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

  • state: Cihazın katlanmış durumu (FLAT veya HALF_OPENED)

  • orientation: Katlama veya menteşenin yönü, HORIZONTAL veya VERTICAL

  • occlusionType: Katlama veya menteşe, ekranın bir kısmını gizliyor mu? NONE veya FULL

  • isSeparating: Katlama veya menteşenin iki mantıksal görüntüleme alanı oluşturup oluşturmadığı doğru veya yanlış

HALF_OPENED özelliği olan bir katlanabilir cihaz isSeparating değerini her zaman doğru olarak bildirir çünkü ekran iki görüntüleme alanına ayrılmış. Ayrıca, isSeparating Uygulama, çift ekranlı cihazlarda her iki özelliği de kapsayan cihazlarda her zaman doğru ekranları.

FoldingFeature bounds mülkü (DisplayFeature adresinden devralındı) 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 WindowInfoTracker 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<FoldingFeature>()
                        .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ü duruşu

Uygulamanız, FoldingFeature nesnesindeki bilgileri kullanarak Telefon bir yüzeyde olduğu, menteşesi ise tam arkaya yerleştirildiğinde yatay konumda ve katlanabilir ekranın yarım açık durumda olduğunu gösterir.

Masa üstü duruşu, kullanıcılara telefonlarını tabletleri kullanmadan rahatça kullanma imkanı sunar. elinde tutmuştu. Masa üstü duruşu medya içerikleri izlemek için ve görüntülü görüşmeler yapabilirsiniz.

Şekil 1. Masaüstü duruşuyla çalışan bir video oynatıcı uygulaması.

Cihazın masaüstü modunda olup olmadığını belirlemek için FoldingFeature.State ve FoldingFeature.Orientation parametrelerini 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ünde durduğundan emin olduktan sonra uygulama düzeninizi güncelleyin buna göre hazırlar. Medya uygulamaları için bu, genellikle oynatma düğmesini ekranın üst kısmına yerleştirmek ve eller serbest izleme ya da dinleme deneyimi için kontrolleri ve ek içeriği hemen altına yerleştirmek anlamına gelir.

Android 15 (API düzeyi 35) ve sonraki sürümlerde aşağıdaki işlemler için eşzamanlı API çağırabilirsiniz: cihazın mevcut hava durumuna bakılmaksızın masa üstü duruşunu destekleyip desteklemediğini cihazın durumunu kontrol edebilirsiniz.

API, cihaz tarafından desteklenen duruşların listesini sağlar. Liste uygulama düzeninizi destekleyici şekilde bölebilirsiniz. ayrıca uygulamanızın kullanıcı arayüzünde masa üstü ve tam ekran düzenler için A/B testleri yapın.

Kotlin

if (WindowSdkExtensions.getInstance().extensionsVersion >= 6) {
    val postures = WindowInfoTracker.getOrCreate(context).supportedPostures
    if (postures.contains(TABLE_TOP)) {
        // Device supports tabletop posture.
   }
}

Java

if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 6) {
    List<SupportedPosture> postures = WindowInfoTracker.getOrCreate(context).getSupportedPostures();
    if (postures.contains(SupportedPosture.TABLETOP)) {
        // Device supports tabletop posture.
    }
}

Örnekler

Kitap duruşu

Katlanabilir cihazlarda bulunan bir diğer benzersiz özellik de cihazın yarı açık ve menteşenin dikey olduğu kitap modudur. Kitabın duruşu, e-kitapları okumak için idealdir. Katlanabilir cihazın büyük ekranında ciltli bir kitap gibi açılan iki sayfalık bir düzenle kitap modu, gerçek bir kitap okuma deneyimini yakalar.

Farklı bir açıdan yakalamak isterseniz fotoğrafçılık için de kullanılabilir en boy oranını gösterir.

Kitabın duruşunu, masa üstü duruşu için kullanılan tekniklerle uygulayın. Tek fark, kodun katlama özelliğinin yönü için yatay yerine dikey değeri 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ındaki bir değişiklik sonucunda uygulamanın görüntüleme alanı değişebilir. Örneğin, cihaz katlanmış veya açılmışsa ya da döndürüldüğünde veya bir pencerenin yeniden boyutlandırıldı.

Jetpack WindowManager WindowMetricsCalculator sınıfı, mevcut ve maksimum pencere metriklerini almanıza olanak tanır. Platform gibiyim WindowMetrics API düzeyi 30'da kullanıma sunulan WindowManager WindowMetrics pencere sınırlarını sağlar ancak API geriye dönük uyumludur aşağı tüketim.

Pencere boyutu sınıflarını kullanma başlıklı makaleyi inceleyin.

Ek kaynaklar

Örnekler

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

Codelab uygulamaları