Bir çok yazılım projesinde arayüz tasarım çok önemlidir. Sade, şık, kullanıcının dikkatini çeken tasarımların barındığı projeler her zaman diğer projelerden bir adım önde olmasını sağlar. Yazılım tasarımlarında animasyonlarda çokça kullanılan özelliklerden biridir.
Google I/O 2018 konferansında Android uygulama geliştiricileri için, daha kolay ve kısa zamanda animasyonları eklemeyi sağlayan MotionLayout
widget’ı duyurdular.
Bu makalemde MotionLayout widget’ı Android projelerinize nasıl ekleyeceğinizi ve onunla birkaç farklı animasyonu nasıl oluşturabileceğinizi göstereceğim.
MotionLayout widget nedir?
MotionLayout widget, artık Android support library (Android destek kütüphanesi) içeresinde barınmasıyla birlikte ConstraintLayout widget’ın yeni özellklerinden biridir.
Sadece XML kodlama kullanarak animasyonları canlandırabilmenizi sağlayan benzersiz bir widget’dır. Dahası, tüm animasyonlar üzerinde ince ayarlar yaparak, kontrolü sağlamamıza imkan sunmaktadır.
MotionLayout widget alakalı örneklerimize başlayalım.
Ön Koşullar
MotionLayout widget’ı kullanabilmak için ihtiyacınız olanlar;
- Android Studio 3.1.3 veya bu sürüm üstü olan bir Android Studio Ide’si
- Android API 21 veya bu API’den daha yüksek sürüme sahip bir cihaz veya emülatör
- En azından temel seviyede ConstraintLayout widget yapısını bilmek
1-Gerekli Kütüphanelerin Eklenmesi
Android Studio Ide ile oluşturduğum projemin app dizinin altındaki build.gradle dosyasını açıyoruz. Dependencies kod bloklarının arasına aşağıdaki kodları yerleştirerek Android destek kütüphanesi ve ConstraintLayout’un en son versiyonlarını yüklüyoruz.
1 2 |
implementation 'com.android.support:appcompat-v7:27.0.2' implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha1' |
2- MotionLayout Tanımlama
res->layout dizinimizin içerisine root elementi MotionLayout olan bir layout dosyası açmalısınız. Örnek kod;
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/motion_container"> <!-- More code here --> </android.support.constraint.motion.MotionLayout> |
Backround rengi olan bir Imageview nesnesine animasyonlar katarak örneklerimizi gerçekleştireceğiz. Imageview arayüz elementini oluşturalım.
1 2 3 4 5 |
<ImageView android:id="@+id/actor" app:srcCompat="@color/colorAccent" android:layout_width="wrap_content" android:layout_height="wrap_content" /> |
Ardından, animasyonları başlatmak için basabileceğiniz bir button ekleyin. Aşağıdaki kod, buttonu layout un ortasına nasıl konumlandıracağınızı gösterir:
1 2 3 4 5 6 7 8 9 10 |
<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Press Me" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:onClick="start"/> |
Ek olarak, animasyonların ilerlemesini izlemek için, bir SeekBar widget’ını layout’a ekleyin.
1 2 3 4 5 6 7 8 |
<SeekBar android:layout_width="100dp" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="10dp" android:id="@+id/seekbar"/> |
Son olarak, button’a tıklağınızda, bu eylemi dinleyebileceğiniz, kısa kodu ekleyiniz.
1 2 3 |
fun start(v: View) { // More code here } |
3- Motion Scene Oluşturma
Motion scene, bir MotionLayout widget’ıyla oluşturmak istediğiniz animasyonla ilgili ayrıntıları içeren ayrı bir XML dosyasıdır.
Root elementi Motion scene olan bir layout dosyası açmalısınız. Örnek kod;
1 2 3 4 5 6 7 8 |
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- More code here --> </MotionScene> |
Bir hareket sahnesi, bir widget’a animasyonda farklı noktalarda uygulanması gereken constraint’ler belirten ConstraintSet öğelerini içerir. Hareketli sahne dosyaları genellikle iki constraint içerir: biri animasyonun başlangıcı için ve bir tanesi son içindir.
Aşağıdaki kod, MotionLayout widget’ının ImageView widget’ını ekranın sağ alt köşesinden sol üst köşeye taşımasına yardımcı olacak iki constraint ‘in nasıl oluşturulacağını gösterir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<ConstraintSet android:id="@+id/starting_set"> <Constraint android:id="@+id/actor" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" android:layout_width="60dp" android:layout_height="60dp" /> </ConstraintSet> <ConstraintSet android:id="@+id/ending_set"> <Constraint android:id="@+id/actor" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" android:layout_width="60dp" android:layout_height="60dp" /> </ConstraintSet> |
MotionLayout widget’ının constraint setlerinin uygulanacağı sırayı anlamasına yardımcı olmak için bir Transition elementi oluşturmalısınız. ConstraintSetStart ve constraintSetEnd özniteliklerini kullanarak, hangisinin ilk uygulanacağını ve hangisinin sonlanacağını belirtebilirsiniz. Transition elementi ayrıca animasyonun süresini belirtmenizi sağlar.
1 2 3 4 5 6 |
<Transition android:id="@+id/my_transition" app:constraintSetStart="@+id/starting_set" app:constraintSetEnd="@+id/ending_set" app:duration="2000"> </Transition> |
Şuana kadar motion scene özeliğini xml dosyası hazırlandı. Fakat MotionLayout widget motion scene özeliği ile bağ kurabilmesi için, MotionLayout elementine, layoutDescription özeliği ekleyerek motion scene xml dosya ismini belirtmeniz gerekir. Örnek kod;
1 2 3 4 5 6 7 8 9 10 11 12 |
<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:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/my_scene" android:id="@+id/motion_container"> ... </android.support.constraint.motion.MotionLayout> |
4- Animasyonu Çalıştırma
Uygulamayı çalıştırdığınızda, MotionLayout widget’ı Transition elementi constraintSetStart özniteliğinde belirtilen constraint’ı otomatik olarak uygulayacaktır. Bu nedenle, animasyonu başlatmak için yapmanız gereken tek şey, widget’ın transitionToEnd () yöntemini çağırmaktır. Daha önceki bir adımda oluşturduğunuz onlick eventine eklenecek olan kod aşağıdadır.
1 |
motion_container.transitionToEnd() |
Uygulamayı çalıştırıp, button’a tıkladığınızda aşağıdaki görüntüyü elde edeceksiniz.
5- Key Frame Oluşturma
Animasyonumuzda, ImageView widget’ı düz bir çizgiye benzeyen bir yolda hareket eder. Bunun nedeni, MotionLayout widget’ının, çalışmak için yalnızca iki nokta vermesidir. Yolun şeklini değiştirmek istiyorsanız, başlangıç ve bitiş noktaları arasında kalan birkaç ara nokta sağlamanız gerekir. Bunu yapmak için yeni key frame oluşturmanız gerekir.
Key frame oluşturmaya başlamadan önce, motion scene xml dosyanızda Transition elementine KeyFrameSet eklemek zorundasınız.
1 2 3 4 5 |
<Transition ...> <KeyFrameSet android:id="@+id/my_keys"> <!-- More code here --> </KeyFrameSet> </Transition> |
MotionLayout widget bir çok key frame özeliğine sahiptir. Ben ise sadece KeyPosition ve KeyCycle frame’lerinden bahsedeceğim.
KeyPosition frame, yolun şeklini değiştirmenize yardımcı olanlardır. Bunları oluştururken, target widget’in ID değerini sağladığınızdan, zaman çizgisi boyunca 0 ile 100 arasında herhangi bir sayı ve yüzde olarak belirtilen istenen X veya Y koordinatları gibi bir konum sağladığınızdan emin olun.
Aşağıdaki kodu KeyFrameSet tag leri arasına yazmalısınız.
1 2 3 4 5 6 7 8 9 10 11 |
<KeyPosition app:target="@+id/actor" app:framePosition="30" app:type="deltaRelative" app:percentX="0.85" /> <KeyPosition app:target="@+id/actor" app:framePosition="60" app:type="deltaRelative" app:percentX="1" /> |
ve sonuç;
KeyCycle frame kullanarak, animasyona salınımlar ekleyebilirsiniz. Bunu oluştururken, tekrar target widget’ının Id’sini, zaman çizgisi boyunca bir konum ve salınımın ileri-geri olması için gereken özelliklerin istenen değerini tekrar sağlamanız gerekir.
Aşağıdaki kod, ImageView elementini periyodik olarak 50 derece döndürmek için sinüs dalgası salınımını kullanan bir KeyCycle frame oluşturur.
1 2 3 4 5 6 |
<KeyCycle app:target="@+id/actor" app:framePosition="30" android:rotation="50" app:waveShape="sin" app:wavePeriod="1" /> |
6-Etkileşimli Animasyon Widget Oluşturma
Şuana kadar bir button a tıklayarak, yani tetikleme yaparak animasyonlu widget’lar oluşturduk.Dilerseniz tetikleme için ekstra button vb . arayüz nesnelerine ihtiyaç duymadan da animasyonlu widget’lar oluşturabilirsiniz. MotionLayout widget’ı, animasyonlu widget’lara doğrudan touch event i eklemenize izin verir. MotionLayout widget’ı, on-click ve the on-swipe eventleri desteklemektedir.
Örneğin, buttonu kullanmadan animasyonlu widget’a on-click eventi eklemek istiyorsanız,Transition elementine onclick tag i eklemeniz gerekir.
1 2 3 |
<OnClick app:target="@+id/actor" app:mode="transitionToEnd"/> |
Kullanıcının ImageView widget’ını ekran boyunca elle sürüklemesine izin vermek için OnSwipe öğesini kullanabilirsiniz. Öğeyi oluştururken, sürükleme kolu olarak hareket etmesi gereken doğru sürükle yönünü ve pencere öğesinin yan tarafını sağladığınızdan emin olmalısınız.
1 2 3 4 |
<OnSwipe app:touchAnchorId="@+id/actor" app:touchAnchorSide="top" app:dragDirection="dragUp" /> |
Artık Android uygulamalarınıza karmaşık, etkileşimli animasyonlar eklemek için MotionLayout widget’ını nasıl kullanacağınızı biliyorsunuz.
Kaynaklar
1- https://code.tutsplus.com/tutorials/creating-animations-with-motionlayout-for-android–cms-31497
2- https://medium.com/google-developers/introduction-to-motionlayout-part-i-29208674b10d