MotionLayout ile hareketleri ve widget animasyonunu yönetme

Oluşturma yöntemini deneyin
Android için önerilen kullanıcı arayüzü araç seti Jetpack Compose'dur. Oluşturma'da animasyonları nasıl kullanacağınızı öğrenin.

MotionLayout, uygulamanızda hareketi ve widget animasyonunu yönetmenize yardımcı olan bir düzen türüdür. MotionLayout, ConstraintLayout sınıfının alt sınıfıdır ve zengin düzen özelliklerini temel alır. ConstraintLayout kitaplığının bir parçası olarak MotionLayout, destek kitaplığı olarak kullanılabilir.

MotionLayout, mülk animasyon çerçevesi, TransitionManager ve CoordinatorLayout arasında bir özellik karışımı sunarak sayfa düzeni geçişleri ile karmaşık hareket işlemleri arasındaki boşluğu doldurur.

Şekil 1. Temel dokunmatik kontrollü hareket.

MotionLayout, düzenler arasındaki geçişleri açıklamanın yanı sıra tüm düzen özelliklerini animasyonlu hale getirmenize olanak tanır. Ayrıca, izlenebilir geçişleri doğal olarak destekler. Bu sayede, geçişteki herhangi bir noktayı dokunma girişi gibi bir koşula göre anında gösterebilirsiniz. MotionLayout, anahtar kareleri de destekler. Böylece, ihtiyaçlarınıza göre tamamen özelleştirilmiş geçişler yapabilirsiniz.

MotionLayout tamamen açıklayıcıdır. Yani ne kadar karmaşık olursa olsun tüm geçişleri XML'de tanımlayabilirsiniz.

Tasarımla ilgili dikkat edilmesi gereken noktalar

MotionLayout, kullanıcıların etkileşimde bulunduğu kullanıcı arayüzü öğelerini (ör. düğmeler ve başlık çubuğu) taşımak, yeniden boyutlandırmak ve animasyonlu hale getirmek için tasarlanmıştır. Uygulamanızda gereksiz bir özel efekt olarak hareket kullanmayın. Kullanıcıların, uygulamanızın ne yaptığını anlamasına yardımcı olmak için kullanın. Uygulamanızı hareketle tasarlama hakkında daha fazla bilgi için Hareketi anlama başlıklı Materyal Tasarım bölümüne bakın.

Başlayın

Projenizde MotionLayout kullanmaya başlamak için aşağıdaki adımları uygulayın.

  1. ConstraintLayout bağımlılığını ekleyin: Projenizde MotionLayout kullanmak için ConstraintLayout 2.0 bağımlılığını uygulamanızın build.gradle dosyasına ekleyin. AndroidX kullanıyorsanız aşağıdaki bağımlılık

    EskiKotlin
    dependencies {
        implementation
    "androidx.constraintlayout:constraintlayout:2.2.0-beta01"
       
    // To use constraintlayout in compose
        implementation
    "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01"
    }
    dependencies {
        implementation
    ("androidx.constraintlayout:constraintlayout:2.2.0-beta01")
       
    // To use constraintlayout in compose
        implementation
    ("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01")
    }
  2. MotionLayout dosyası oluşturun: MotionLayout, ConstraintLayout sınıfının alt sınıfıdır. Bu nedenle, aşağıdaki örneklerde gösterildiği gibi, düzen kaynak dosyanızdaki sınıf adını değiştirerek mevcut tüm ConstraintLayout sınıflarını MotionLayout sınıfına dönüştürebilirsiniz:

    <!-- before: ConstraintLayout -->
    <androidx.constraintlayout.widget.ConstraintLayout .../>
    <!-- after: MotionLayout -->
    <androidx.constraintlayout.motion.widget.MotionLayout .../>
              
    <!-- before: ConstraintLayout -->
    <android.support.constraint.ConstraintLayout .../>
    <!-- after: MotionLayout -->
    <android.support.constraint.motion.MotionLayout .../>
              

    Şekil 1'de gösterilen düzeni tanımlayan bir MotionLayout dosyasının tam örneğini aşağıda bulabilirsiniz:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- activity_main.xml -->
    <androidx.constraintlayout.motion.widget.MotionLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/motionLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutDescription="@xml/scene_01"
        tools:showPaths="true">
    
        <View
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:background="@color/colorAccent"
            android:text="Button" />
    
    </androidx.constraintlayout.motion.widget.MotionLayout>
            
    <?xml version="1.0" encoding="utf-8"?>
    <!-- activity_main.xml -->
    <android.support.constraint.motion.MotionLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/motionLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutDescription="@xml/scene_01"
        tools:showPaths="true">
    
        <View
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:background="@color/colorAccent"
            android:text="Button" />
    
    </android.support.constraint.motion.MotionLayout>
            
  3. MotionScene oluşturun: Önceki MotionLayout örneğinde, app:layoutDescription özelliği bir hareket sahnesine referans veriyor. Hareketli sahne, bir XML kaynak dosyasıdır. Hareket sahnesi, <MotionScene> kök öğesinde ilgili düzenin tüm hareket açıklamalarını içerir. Düzenleme bilgilerini hareket açıklamalarından ayrı tutmak için her MotionLayout, ayrı bir hareket sahnesine referans verir. Hareket sahnesindeki tanımlar, MotionLayout içindeki benzer tanımlara göre önceliklidir.

    Aşağıda, 1. resimdeki temel yatay hareketi açıklayan örnek bir hareket sahnesi dosyası verilmiştir:

    <?xml version="1.0" encoding="utf-8"?>
    <MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:motion="http://schemas.android.com/apk/res-auto">
    
        <Transition
            motion:constraintSetStart="@+id/start"
            motion:constraintSetEnd="@+id/end"
            motion:duration="1000">
            <OnSwipe
                motion:touchAnchorId="@+id/button"
                motion:touchAnchorSide="right"
                motion:dragDirection="dragRight" />
        </Transition>
    
        <ConstraintSet android:id="@+id/start">
            <Constraint
                android:id="@+id/button"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:layout_marginStart="8dp"
                motion:layout_constraintBottom_toBottomOf="parent"
                motion:layout_constraintStart_toStartOf="parent"
                motion:layout_constraintTop_toTopOf="parent" />
        </ConstraintSet>
    
        <ConstraintSet android:id="@+id/end">
            <Constraint
                android:id="@+id/button"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:layout_marginEnd="8dp"
                motion:layout_constraintBottom_toBottomOf="parent"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintTop_toTopOf="parent" />
        </ConstraintSet>
    
    </MotionScene>
        

    Aşağıdakileri göz önünde bulundurun:

    • <Transition> hareketin temel tanımını içerir.

      • motion:constraintSetStart ve motion:constraintSetEnd, hareketin uç noktalarına referans verir. Bu uç noktalar, hareket sahnesinin sonraki kısımlarında <ConstraintSet> öğelerinde tanımlanır.

      • motion:duration, hareketin tamamlanması için gereken milisaniye sayısını belirtir.

    • <OnSwipe> hareket için dokunma kontrolü oluşturmanıza olanak tanır.

      • motion:touchAnchorId, kullanıcının kaydırıp sürükleyebileceği görünümü ifade eder.

      • motion:touchAnchorSide, görünümün sağ taraftan sürüklendiğini gösterir.

      • motion:dragDirection, sürüklemenin ilerleme yönünü ifade eder. Örneğin, motion:dragDirection="dragRight", görünüm sağa sürüklenirken ilerlemenin arttığı anlamına gelir.

    • <ConstraintSet> hareketinizi tanımlayan çeşitli kısıtlamaları tanımladığınız yerdir. Bu örnekte, hareketinizin her bir uç noktası için bir <ConstraintSet> tanımlanmıştır. Bu uç noktalar, app:layout_constraintTop_toTopOf="parent" ve app:layout_constraintBottom_toBottomOf="parent" kullanılarak dikey olarak ortalanmaktadır. Yatay olarak uç noktalar, ekranın en sol ve en sağ taraflarındadır.

    Hareket sahnesinin desteklediği çeşitli öğelere daha ayrıntılı bir bakış için MotionLayout örneklerine bakın.

Eşlenen özellikler

Hareketli sahne dosyasında ConstraintSet öğeleri, geçiş sırasında ara değere sahip olan ek özellikler içerebilir. Konum ve sınırlara ek olarak aşağıdaki özellikler MotionLayout tarafından ara değer olarak hesaplanır:

  • alpha
  • visibility
  • elevation
  • rotation, rotationX, rotationY
  • translationX, translationY, translationZ
  • scaleX, scaleY

Özel özellikler

<Constraint> içinde, konum veya View özellikleriyle ilgili olmayan özellikler için geçiş belirtmek üzere <CustomAttribute> öğesini kullanabilirsiniz.

<Constraint
    android:id="@+id/button" ...>
    <CustomAttribute
        motion:attributeName="backgroundColor"
        motion:customColorValue="#D81B60"/>
</Constraint>

<CustomAttribute>'ler kendi özelliklerine sahiptir:

  • motion:attributeName gereklidir ve bir nesneyle, alıcı ve ayarlayıcı yöntemleriyle eşleşmelidir. Geter ve setter belirli bir kalıpla eşleşmelidir. Örneğin, görünümde temel getBackgroundColor() ve setBackgroundColor() yöntemleri bulunduğundan backgroundColor desteklenir.
  • Sağlamanız gereken diğer özellik, değer türüne bağlıdır. Aşağıdaki desteklenen türler arasından seçim yapın:
    • motion:customColorValue için renkler
    • Tam sayılar için motion:customIntegerValue
    • motion:customFloatValue için kayan
    • Dizeler için motion:customStringValue
    • Boyutlar için motion:customDimension
    • Boole değerleri için motion:customBoolean

Özel özellik belirtirken hem başlangıç hem de bitiş <ConstraintSet> öğelerinde uç nokta değerlerini tanımlayın.

Arka plan rengini değiştir

Önceki örnekten yola çıkarak, görünümün renklerinin hareketinin bir parçası olarak şekil 2'de gösterildiği gibi değişmesini istediğinizi varsayalım.

Şekil 2. Görünüm, hareket ettikçe arka plan rengini değiştirir.

Aşağıdaki kod snippet'inde gösterildiği gibi her ConstraintSet öğesine bir <CustomAttribute> öğesi ekleyin:

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginStart="8dp"
        motion:layout_constraintBottom_toBottomOf="parent"
        motion:layout_constraintStart_toStartOf="parent"
        motion:layout_constraintTop_toTopOf="parent">
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#D81B60" />
    </Constraint>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginEnd="8dp"
        motion:layout_constraintBottom_toBottomOf="parent"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintTop_toTopOf="parent">
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#9999FF" />
    </Constraint>
</ConstraintSet>

Ek MotionLayout özellikleri

MotionLayout, önceki örnekteki özelliklere ek olarak belirtmek isteyebileceğiniz başka özelliklere de sahiptir:

  • app:applyMotionScene="boolean", hareket sahnesinin uygulanıp uygulanmayacağını belirtir. Bu özelliğin varsayılan değeri true.
  • app:showPaths="boolean", hareket devam ederken hareket yollarının gösterilip gösterilmeyeceğini belirtir. Bu özelliğin varsayılan değeri false.
  • app:progress="float", geçiş ilerleme durumunu açıkça belirtmenize olanak tanır. 0 (geçişin başlangıcı) ile 1 (geçişin sonu) arasında herhangi bir kayan nokta değeri kullanabilirsiniz.
  • app:currentState="reference", belirli bir ConstraintSet belirtmenize olanak tanır.
  • app:motionDebug, hareketle ilgili ek hata ayıklama bilgilerini görüntülemenize olanak tanır. Olası değerler "SHOW_PROGRESS", "SHOW_PATH" veya "SHOW_ALL"'dir.

Ek kaynaklar

MotionLayout hakkında daha fazla bilgi için aşağıdaki kaynaklara göz atın: