Katlanabilir cihazlara uygun tasarım

ConstraintLayout 2.1 sürümüne katlanabilir cihazları yönetmeye yardımcı olmak için SharedValues ve ReactiveGuide gibi çok sayıda özelliğin yanı sıra MotionLayout ile animasyon için gelişmiş destek gibi çeşitli özellikler eklendi.

Paylaşılan Değerler

ConstraintLayout çalışma zamanı değerlerini eklemek için yeni bir mekanizma ekledik. Tüm ConstraintLayout örnekleri bu değere erişebildiğinden, bu mekanizmanın sistem genelindeki değerler için kullanılması amaçlanmıştır.

Katlanabilir cihazlarda, çalışma zamanında ekranın konumunu eklemek için şu mekanizmayı kullanabiliriz:

Kotlin

ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)

Java

ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);

Özel bir yardımcıda, herhangi bir değişiklik için işleyici ekleyerek paylaşılan değerlere erişebilirsiniz:

Kotlin

val sharedValues: SharedValues = ConstraintLayout.getSharedValues()
sharedValues.addListener(mAttributeId, this)

Java

SharedValues sharedValues = ConstraintLayout.getSharedValues();
sharedValues.addListener(mAttributeId, this);

Jetpack WindowManager kitaplığını kullanarak ekranın konumunu nasıl yakaladığımızı ve konumu ConstraintLayout içine nasıl eklediğimizi görmek için Foldable Experiments örneğine bakabilirsiniz.

Kotlin

inner class StateContainer : Consumer<WindowLayoutInfo> {

    override fun accept(newLayoutInfo: WindowLayoutInfo) {

        // Add views that represent display features
        for (displayFeature in newLayoutInfo.displayFeatures) {
            val foldFeature = displayFeature as? FoldingFeature
            if (foldFeature != null) {
                if (foldFeature.isSeparating &&
                    foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
                ) {
                    // The foldable device is in tabletop mode
                    val fold = foldPosition(motionLayout, foldFeature)
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
                } else {
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0);
                }
            }
        }
    }
}

Java

class StateContainer implements Consumer<WindowLayoutInfo> {

    @Override
    public void accept(WindowLayoutInfo newLayoutInfo) {

        // Add views that represent display features
        for (DisplayFeature displayFeature : newLayoutInfo.getDisplayFeatures()) {
            if (displayFeature instanceof FoldingFeature) {
                FoldingFeature foldFeature = (FoldingFeature)displayFeature;
                if (foldFeature.isSeparating() &&
                    foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL
                ) {
                    // The foldable device is in tabletop mode
                    int fold = foldPosition(motionLayout, foldFeature);
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
                } else {
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0);
                }
            }
        }
    }
}

fireNewValue(), değeri ilk parametre ve eklenecek değeri ikinci parametre olarak temsil eden bir kimliği alır.

ReactiveGuide

Kod yazmak zorunda kalmadan bir düzendeki SharedValue öğesinden yararlanmanın bir yolu, ReactiveGuide yardımcısını kullanmaktır. Bu işlem, bağlı SharedValue öğesine göre yatay veya dikey bir kılavuz oluşturur.

    <androidx.constraintlayout.widget.ReactiveGuide
        android:id="@+id/fold"
        app:reactiveGuide_valueId="@id/fold"
        android:orientation="horizontal" />

Ardından, standart bir yönergeyle aynı şekilde kullanılabilir.

Katlanabilir cihazlar için MotionLayout

2.1 sürümünde MotionLayout sürümüne, dönüşüm durumunun değiştirilmesine yardımcı olan çeşitli özellikler ekledik. Genellikle olası farklı düzenler arasında animasyon oluşturmak zorunda kaldığımız için katlanabilir cihazlarda özellikle kullanışlı bir işleve sahip olduk.

Katlanabilir cihazlar için iki yaklaşım vardır:

  • Çalışma zamanında, mevcut düzeninizi (ConstraintSet) ekranın gösterileceği veya gizleneceği şekilde güncelleyin.
  • Desteklemek istediğiniz her bir katlanabilir durum için ayrı bir ConstraintSet kullanın (closed, folded veya fully open).

ConstraintSet animasyonu

MotionLayout içindeki updateStateAnimate() işlevi 2.1 sürümünde eklenmiştir:

Kotlin

fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)

Java

void updateStateAnimate(int stateId, ConstraintSet set, int duration);

Bu işlev, belirli bir ConstraintSet uygulamasını güncellerken anında güncelleme yapmak yerine değişiklikleri otomatik olarak animasyon eder. Bunu updateState(stateId, constraintset) ile yapabilirsiniz. Böylece, bulunduğunuz katlanabilir cihaz durumu gibi değişikliklere bağlı olarak kullanıcı arayüzünüzü anında güncelleyebilirsiniz.

MotionLayout içinde ReactiveGuide

ReactiveGuide, MotionLayout içinde kullanıldığında iki faydalı özelliği de destekler:

  • app:reactiveGuide_animateChange="true|false"

  • app:reactiveGuide_applyToAllConstraintSets="true|false"

İlki, mevcut ConstraintSet öğesini değiştirir ve değişikliği otomatik olarak canlandırır. İkincisi, ReactiveGuide konumunun yeni değerini MotionLayout içindeki tüm ConstraintSet'lere uygular. Katlanabilir cihazlar için tipik bir yaklaşım, katlama konumunu temsil eden bir ReactiveGuide kullanarak düzen öğelerinizi ReactiveGuide göreli ayarlamaktır.

Katlanabilir cihaz durumunu göstermek için birden fazla ConstraintSet kullanma

Kullanıcı arayüzünüzü katlanabilir cihazları destekleyecek şekilde tasarlamanın mevcut MotionLayout durumunu güncellemek yerine belirli ayrı durumlar (closed, folded ve fully open dahil) oluşturabilirsiniz.

Bu senaryoda, ekran birimini temsil etmek için yine de ReactiveGuide kullanmak isteyebilirsiniz, ancak her bir durumun bir başkasına nasıl geçeceği üzerinde çok daha fazla kontrole (mevcut ConstraintSet güncellenirken kullanılan otomatik animasyona kıyasla) sahip olursunuz.

Bu yaklaşımla, DeviceState işleyicinizde MotionLayout öğesini MotionLayout.transitionToState(stateId) yöntemi aracılığıyla belirli durumlara geçiş yapmaya yönlendirirsiniz.