MotionLayout, uygulamanızdaki hareket ve widget animasyonunu 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 bu sınıfın zengin düzen özelliklerini temel alır. ConstraintLayout kitaplığının bir parçası olan MotionLayout
destek kitaplığı olarak kullanılabilir.
MotionLayout, düzen geçişleri ile karmaşık hareket işleme arasındaki boşluğu doldurarak özellik animasyonu çerçevesi, TransitionManager ve CoordinatorLayout arasında bir özellik karışımı sunar.
MotionLayout, düzenler arasındaki geçişleri açıklamanın yanı sıra düzen özelliklerini de animasyonlu hale getirmenize olanak tanır. Ayrıca, aranabilir geçişleri doğal olarak destekler. Bu, dokunma girişi gibi bir koşula bağlı olarak geçişteki herhangi bir noktayı anında gösterebileceğiniz anlamına gelir. MotionLayout ayrıca anahtar kareleri de destekler. Bu sayede, ihtiyaçlarınıza uygun tamamen özelleştirilmiş geçişler yapabilirsiniz.
MotionLayout tamamen bildirimseldir. Bu nedenle, ne kadar karmaşık olursa olsun tüm geçişleri XML'de tanımlayabilirsiniz.
Tasarım konusunda 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 animasyon eklemek için tasarlanmıştır. Uygulamanızda hareketi gereksiz bir özel efekt olarak 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 Material Design bölümündeki Understanding
motion (Hareketi Anlama) başlıklı makaleyi inceleyin.
Başlayın
Projenizde MotionLayout kullanmaya başlamak için aşağıdaki adımları uygulayın.
-
ConstraintLayoutbağımlılığını ekleyin: ProjenizdeMotionLayoutkullanmak için uygulamanızınbuild.gradledosyasınaConstraintLayout2.0 bağımlılığını ekleyin. AndroidX kullanıyorsanız aşağıdaki bağımlılığı ekleyin:Eski
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.1" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.1") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1") }
-
MotionLayoutdosyası oluşturun:MotionLayout,ConstraintLayoutsınıfının bir alt sınıfıdır. Bu nedenle, düzen kaynağı dosyanızdaki sınıf adını aşağıdaki örneklerde gösterildiği gibi değiştirerek mevcutConstraintLayoutsınıflarınıMotionLayoutsınıfına 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 bir
MotionLayoutdosyasının tam ö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>
-
MotionScene oluşturma: Önceki
MotionLayoutörneğinde,app:layoutDescriptionözelliği bir MotionScene'e referans veriyor. Hareket sahnesi, bir XML kaynak dosyasıdır. Bir hareket sahnesi,<MotionScene>kök öğesi içinde ilgili düzene ait tüm hareket açıklamalarını içerir. Düzen bilgilerini hareket açıklamalarından ayrı tutmak için herMotionLayout, ayrı bir hareket sahnesine referans verir. Hareket sahnesindeki tanımlar,MotionLayoutiçindeki benzer tanımlardan önceliklidir.Şekil 1'deki temel yatay hareketi açıklayan örnek bir hareket sahnesi dosyasını aşağıda bulabilirsiniz:
<?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:constraintSetStartvemotion:constraintSetEnd, hareketin uç noktalarına referans verir. 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ş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ği anlamına gelir. -
motion:dragDirection, sürüklemenin ilerleme yönünü gösterir. Örneğin,motion:dragDirection="dragRight", görünüm sağa sürüklendikçe ilerlemenin arttığı anlamına gelir.
-
-
<ConstraintSet>, hareketinizi tanımlayan çeşitli kısıtlamaları tanımladığınız yerdir. Bu örnekte, hareketinizin her uç noktası için bir<ConstraintSet>tanımlanır. Bu uç noktalar,app:layout_constraintTop_toTopOf="parent"veapp:layout_constraintBottom_toBottomOf="parent"kullanılarak dikey olarak ortalanır. Yatay olarak, uç noktalar ekranın en sol ve en sağ taraflarında yer alır.
Hareket sahnesinin desteklediği çeşitli öğeler hakkında daha ayrıntılı bilgi için MotionLayout örnekleri bölümüne bakın.
-
İnterpolasyonlu özellikler
Bir hareket sahnesi dosyasındaki ConstraintSet öğeleri, geçiş sırasında enterpolasyon yapılan ek özellikler içerebilir. Konum ve sınırlara ek olarak aşağıdaki özellikler MotionLayout tarafından enterpolasyon yapılır:
alphavisibilityelevationrotation,rotationX,rotationYtranslationX,translationY,translationZscaleX,scaleY
Özel özellikler
<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>
Bir <CustomAttribute> iki özelliğe sahiptir:
motion:attributeNamegereklidir ve getter ve setter yöntemleri olan bir nesneyle eşleşmelidir. Getter ve setter belirli bir kalıpla eşleşmelidir. Örneğin, görünümde temel alınangetBackgroundColor()vesetBackgroundColor()yöntemleri olduğundanbackgroundColordesteklenir.- 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:customColorValuerenkler için- Tam sayılar için
motion:customIntegerValue motion:customFloatValueiçin kayanlar- Dizeler için
motion:customStringValue motion:customDimensionboyutlar içinmotion:customBooleanBoole değerleri için
Özel bir özellik belirtirken uç nokta değerlerini hem başlangıç hem de bitiş <ConstraintSet> öğelerinde tanımlayın.
Arka plan rengini değiştirme
Önceki örnekten devam edersek, 2. şekilde gösterildiği gibi, görünümün renklerinin hareketinin bir parçası olarak değişmesini istediğinizi varsayalım.
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
Önceki örnekteki özelliklere ek olarak, MotionLayout öğesinin belirtmek isteyebileceğiniz başka özellikleri de vardır:
app:applyMotionScene="boolean", hareket sahnesinin uygulanıp uygulanmayacağını gösterir. Bu özelliğin varsayılan değeritrueşeklindedir.app:showPaths="boolean", hareket çalışırken hareket yollarının gösterilip gösterilmeyeceğini belirtir. Bu özelliğin varsayılan değerifalseşeklindedir.app:progress="float", geçiş ilerlemesini açıkça belirtmenize olanak tanır.0(geçişin başlangıcı) ile1(geçişin sonu) arasındaki herhangi bir kayan nokta değerini kullanabilirsiniz.app:currentState="reference", belirli birConstraintSetbelirtmenize 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 bakın:
- Advanced Android in Kotlin 03.2: Animation with MotionLayout
- MotionLayout örnekleri
- GitHub'da MotionLayout/ConstraintLayout örnekleri
- MotionLayout'a giriş (1. bölüm)
- MotionLayout'a giriş (II. bölüm)
- MotionLayout'a giriş (bölüm III)
- MotionLayout'a giriş (IV. bölüm)