MotionLayout Kullanımına başlamadan önce, MotionLayout nedir ve ne işe yarar, gelin birlikte öğrenelim.
Android IO 2020 geliştirici konferansında tanıtılması beklenen ancak Covid-19 salgını nedeniyle organizasyon gerçekleşemeyen yeniliklerden biri olan MotionLayout, Android 4.0 ile birlikte hayatımıza giren güçlü bir araçtır.
Yukarıdaki videoda Rebecca Franks, MotionLayout ile ilgili temel bilgileri bizlerle paylaşıyor. Ayrıca bu linkten sunuma da ulaşabilirsiniz.
- ConstraintLayout sınıfının bir alt sınıfıdır.
- View’lar üzerinde animasyonlar yapmayı kolaylaştırır.
- İnteraktif ve karmaşık animasyonlar oluşturmayı sağlar.
- Animasyonların ara durumlarına programatik olarak erişim sağlar.
- API 14 ve üzeri sürümlerle uyumludur.
GitHub'da @nikhilpanju'nun FabFilter projesi, MotionLayout kullanımı için güzel bir örnektir.
MotionLayout'u Projeye Ekleme
Öncelikle, gradle dosyanızın dependencies bloğuna aşağıdaki satırı eklemelisiniz:
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
Daha sonra, layout dosyanızda kullandığınız <androidx.constraintlayout.widget.ConstraintLayout> etiketini, <androidx.constraintlayout.motion.widget.MotionLayout> olarak değiştirmeniz yeterlidir.
Animasyonların Tanımlanması: motion_scene.xml
Animasyonlarınızı kontrol etmek için app/res/xml klasörüne motion_scene.xml adında bir dosya oluşturmalısınız. Dosyanın varsayılan içeriği aşağıdaki gibi olur:
<?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">
</MotionScene>
Bu XML dosyasını MotionLayout nesnemize bağlamak için layout dosyanızda aşağıdaki gibi kullanmalısınız:
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motionLayout"
app:layoutDescription="@xml/motion_scene"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.motion.widget.MotionLayout>
Eğer Android Studio’da ConstraintLayout’u MotionLayout olarak değiştirdiğinizde, sizden otomatik olarak bir motion_scene.xml dosyası oluşturmanız istenir. Bu dosya, aşağıdaki gibi başlangıç ve bitiş durumlarını tanımlayan ConstraintSet ve Transition etiketlerini içerir:
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/widget" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@id/widget" />
</ConstraintSet>
<Transition
app:constraintSetStart="@+id/start"
app:constraintSetEnd="@id/end"
app:duration="1000"
app:motionInterpolator="linear" />
</MotionScene>
MotionScene Nedir?
- Animasyonları tanımlayan XML dosyasıdır.
- Programatik olarak da oluşturulabilir.
- İçerisinde ConstraintSet, Transition ve KeyFrame yapıları bulunur.
Buradaki temel fikir, bir sahnede animasyonların hangi başlangıç ve bitiş durumları arasında gerçekleşeceğini tanımlamaktır. Animasyonun nasıl ve ne kadar sürede olacağını <Transition> elemanı belirlerken, <ConstraintSet> elemanları bu durumların detaylarını tutar.
MotionScene Ağaç Yapısı
<MotionScene>
<Transition>
<KeyFrameSet>
<OnClick>
<OnSwipe>
</Transition>
<ConstraintSet>
<Constraint>
<Transform>
<PropertySet>
<Layout>
<CustomAttribute>
Canlı Örnek
Şimdi bir örnekle MotionLayout’u deneyelim. Öncelikle activity_main.xml dosyamızı aşağıdaki şekilde güncelleyelim:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motionLayout"
app:layoutDescription="@xml/activity_main_scene"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="@+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:background="@color/colorAccent"
tools:layout_editor_absoluteX="147dp"
tools:layout_editor_absoluteY="230dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
Sonrasında, app/res/xml klasöründe activity_main_scene.xml dosyamızı aşağıdaki gibi oluşturalım:
<?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:dragDirection="dragRight"
motion:touchAnchorId="@id/button"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@id/button">
<Layout
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" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end"
motion:deriveConstraintsFrom="@id/start">
<Constraint android:id="@id/button">
<Layout
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintEnd_toEndOf="parent" />
</Constraint>
</ConstraintSet>
</MotionScene>
Bu örnekte, butonumuzu sağa sola kaydırarak basit bir sürükleme animasyonu yapabiliyoruz. Bu hareketlerin animasyonları MotionScene dosyamızda tanımlanmıştır.
Daha fazla örnek ve detaylı bilgi için Android Developer resmi dokümanlarına göz atabilirsiniz.