MotionLayout ile hareketleri ve widget animasyonunu yönetme

MotionLayout, uygulamanızdaki hareketleri ve widget animasyonlarını yönetmenize yardımcı olan bir düzen türüdür. MotionLayout, ConstraintLayout sınıfının bir alt sınıfıdır ve zengin düzen özelliklerini temel alır. MotionLayout, ConstraintLayout kitaplığının bir parçası olarak destek kitaplığı olarak mevcuttur.

MotionLayout, düzen geçişleri ile karmaşık hareket işleme arasındaki boşluğu doldurarak mülk animasyon çerçevesi, TransitionManager ve CoordinatorLayout arasında bir dizi özellik sunar.

Şekil 1. Dokunmayla kontrol edilen temel hareket.

MotionLayout, düzenler arasındaki geçişleri açıklamanın yanı sıra tüm düzen özelliklerini canlandırmanıza da olanak tanır. Dahası, yapısı gereği aranabilir geçişleri destekler. Bu, dokunmatik giriş gibi bazı koşullara göre geçişteki herhangi bir noktayı anında gösterebileceğiniz anlamına gelir. MotionLayout, ihtiyaçlarınıza uygun tamamen özelleştirilmiş geçişler yapabilmenizi sağlayan animasyon karelerini de destekler.

MotionLayout tamamen bildirim temellidir. Yani ne kadar karmaşık olursa olsun XML'de tüm geçişleri açıklayabilirsiniz.

Tasarım ile ilgili dikkat edilmesi gereken noktalar

MotionLayout, kullanıcıların etkileşimde bulunduğu düğmeler ve başlık çubukları gibi kullanıcı arayüzü öğelerini taşımak, yeniden boyutlandırmak ve bunlara animasyon eklemek için tasarlanmıştır. Uygulamanızda gereksiz özel bir efekt olarak hareket kullanmayın. Kullanıcıların, uygulamanızın neler yaptığını anlamasına yardımcı olmak için bunu kullanın. Uygulamanızı hareketle tasarlama hakkında daha fazla bilgi için Hareketi anlama adlı 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ığı ekleyin:

    Modern

    dependencies {
        implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha13"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13"
    }
    

    Kotlin

    dependencies {
        implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13")
        // To use constraintlayout in compose
        implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13")
    }
    
  2. MotionLayout dosyası oluşturun: MotionLayout, ConstraintLayout sınıfının bir 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 ConstraintLayout öğelerini MotionLayout biçimine dönüştürebilirsiniz:

    AndroidX

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

    Destek kitaplığı

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

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

    AndroidX

    <?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>
            

    Destek kitaplığı

    <?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. Bir MotionScene oluşturun: Önceki MotionLayout örneğinde app:layoutDescription özelliği, bir hareket sahnesine referansta bulunur. Hareket sahnesi bir XML kaynak dosyasıdır. Hareket sahnesi, <MotionScene> kök öğesinde ilgili düzene ait tüm hareket açıklamalarını içerir. Düzen bilgilerini hareket açıklamalarından ayrı tutmak için her MotionLayout ayrı bir hareket sahnesini referans alır. Hareket sahnesindeki tanımlar, MotionLayout içindeki benzer tanımlara göre önceliklidir.

    Aşağıda, Şekil 1'deki temel yatay hareketi açıklayan 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 referanslardır. Bu uç noktalar, hareket sahnesinin ilerleyen kısımlarındaki <ConstraintSet> öğelerinde tanımlanır.

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

    • <OnSwipe>, hareket için dokunma kontrolü oluşturabilmenizi sağlar.

      • motion:touchAnchorId, kullanıcının kaydırarak ve sürükleyebilmesini sağlayan görünümü ifade eder.

      • motion:touchAnchorSide, görünümün sağ taraftan sürüklenmekte olduğu anlamına gelir.

      • motion:dragDirection, sürüklemenin ilerleme yönünü belirtir. Örneğin motion:dragDirection="dragRight", görünüm sağa sürüklendikçe ilerleme durumunun artacağı 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 ortalanır. Uç noktalar yatay olarak ekranın en sol ve sağ taraflarındadır.

    Bir hareket sahnesinin desteklediği çeşitli öğeleri daha ayrıntılı bir şekilde incelemek için MotionLayout örneklerine bakın.

İnterpole edilmiş özellikler

Bir hareket sahnesi dosyasında, ConstraintSet öğeleri geçiş sırasında interpolasyon uygulanan ek özellikler içerebilir. Konum ve sınırlara ek olarak, aşağıdaki özellikler MotionLayout tarafından interpolasyona tabi tutulur:

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

Özel özellikler

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

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

<CustomAttribute> kendi başına iki özellik içerir:

  • motion:attributeName gereklidir ve bir nesneyi alıcı ve ayarlayıcı yöntemleriyle eşleştirmelidir. Alıcı ve ayarlayıcı 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:
    • Renkler için motion:customColorValue
    • Tam sayılar için motion:customIntegerValue
    • Kayan noktalar için motion:customFloatValue
    • Dizeler için motion:customStringValue
    • Boyutlar için motion:customDimension
    • Boole için motion:customBoolean

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

Arka plan rengini değiştir

Önceki örneğe dayanarak, Şekil 2'de gösterildiği gibi görünümün renklerinin, hareketi kapsamında değişmesini istediğinizi varsayalım.

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

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

Yukarıdaki örnekteki özelliklere ek olarak, MotionLayout belirtmek isteyebileceğiniz başka özelliklere sahiptir:

  • app:applyMotionScene="boolean", hareket sahnesinin uygulanıp uygulanmayacağını belirtir. Bu özellik için varsayılan değer true şeklindedir.
  • app:showPaths="boolean", hareket devam ederken hareket yollarının gösterilip gösterilmeyeceğini belirtir. Bu özellik için varsayılan değer false şeklindedir.
  • app:progress="float", geçiş işleminin ilerleme durumunu açık bir şekilde belirtmenize olanak tanır. 0 ile 1 (geçişin sonu) arasındaki herhangi bir kayan nokta değerini kullanabilirsiniz.
  • app:currentState="reference", belirli bir ConstraintSet belirtmenizi sağlar.
  • 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 bakın: