Mülk Animasyonuna Genel Bakış

Oluşturma yöntemini deneyin
Jetpack Compose, Android için önerilen kullanıcı arayüzü araç setidir. Oluşturma bölümünde animasyon özelliğini nasıl kullanacağınızı öğrenin.

Mülk animasyon sistemi, neredeyse her şeyi animasyona dönüştürmenize olanak tanıyan güçlü bir çerçevedir. Herhangi bir nesne özelliğini zaman içinde değiştirecek bir animasyon tanımlayabilir, ekrana getirilip gelmemesinden bağımsız olarak. Mülk animasyonu, bir mülkün (nesnedeki bir alan) değerinin belirtilen bir süre boyunca nasıl görüneceğini belirler. Bir nesneyi canlandırmak için canlandırmak istediğiniz nesne özelliğini (ör. nesnenin ekrandaki konumu, ne kadar süre boyunca canlandırmak istediğiniz ve hangi değerler arasında canlandırmak istediğiniz) belirtirsiniz.

Mülk animasyon sistemi, animasyonla ilgili aşağıdaki özellikleri tanımlamanıza olanak tanır:

  • Süre: Animasyonun süresini belirtebilirsiniz. Varsayılan uzunluk 300 ms'dir.
  • Zaman interpolasyonu: Mülke ait değerlerin nasıl hesaplanacağını belirtebilirsiniz. animasyon için geçerli geçen sürenin işlevi.
  • Tekrar sayısı ve davranışı: bir sürenin sonuna geldiğini ve animasyonun kaç kez tekrarlanacağını belirtir. Ayrıca, animasyonun tersten oynatılıp oynatılmayacağını da belirtebilirsiniz. Ters olarak ayarlandığında, animasyon tekrar sayısına ulaşılana kadar tekrar tekrar ileri ve geri oynatılır.
  • Animasyon grupları: Animasyonları birlikte veya sırayla ya da belirtilen gecikmeler sonrasında oynatılacak mantıksal gruplar halinde toplayabilirsiniz.
  • Kare yenileme gecikmesi: Animasyonunuzun karelerinin ne sıklıkta yenileneceğini belirtebilirsiniz. Varsayılan olarak 10 ms'de bir yenileme yapılır ancak uygulamanızın kareleri yenileme hızı, temel olarak sistemin genel olarak ne kadar meşgul olduğuna ve sistemin temel zamanlayıcıyı ne kadar hızlı işleyebileceğine bağlıdır.

Mülk animasyonunun tam bir örneğini görmek için CustomTransition'daki ChangeColor sınıfı örneği ziyaret edin.

Mülk animasyonu nasıl çalışır?

İlk olarak, basit bir örnekle animasyonun nasıl çalıştığını inceleyelim. Şekil 1'de, ekrandaki yatay konumunu temsil eden x özelliğiyle animasyonlu bir hayali nesne gösterilmektedir. Animasyonun süresi 40 ms'ye ve mesafe seyahat 40 pikseldir. Varsayılan kare yenileme hızı olan her 10 ms'de nesne yatay olarak 10 piksel hareket eder. 40 ms. sonunda animasyon durur ve nesne yatay konum 40. Bu, doğrusal aralıklı bir animasyon örneğidir. Yani nesne sabit bir hızda hareket eder.

Şekil 1. Doğrusal animasyon örneği

Animasyonların doğrusal olmayan bir ara değere sahip olmasını da belirtebilirsiniz. Şekil 2'de, animasyonun başında hızlanan ve animasyonun sonunda yavaşlayan varsayımsal bir nesne gösterilmektedir. Nesne yine 40 ms içinde 40 piksel hareket eder ancak bu hareket doğrusal değildir. Bu animasyon başlangıçta yarıya kadar hızlanır, ardından yarıdan animasyonun sonuna kadar yavaşlar. Şekil 2'de gösterildiği gibi, animasyonun başlangıcında ve sonunda kat edilen mesafe, ortasına kıyasla daha azdır.

Şekil 2. Doğrusal olmayan animasyon örneği

Mülk animasyon sisteminin önemli bileşenlerine göz atalım. yukarıda gösterilenler gibi animasyonlar hesaplar. Şekil 3'te ana sınıfların daha iyi olur.

Şekil 3. Animasyonlar nasıl hesaplanır?

ValueAnimator nesnesi, animasyonunuzun zamanlamasını takip eder. animasyonun ne kadar süredir çalıştığı ve etkinleştirildiği özelliğin geçerli değeri gibi daha fazla bilgi edineceksiniz.

ValueAnimator, animasyon ara değerlemesini tanımlayan bir TimeInterpolator ve animasyon uygulanan özelliğin değerlerinin nasıl hesaplanacağını tanımlayan bir TypeEvaluator içerir. Örneğin, Şekil 2'de, TimeInterpolator değeri şöyle olacaktır: AccelerateDecelerateInterpolator ve TypeEvaluator, IntEvaluator olacaktır.

Animasyon başlatmak için bir ValueAnimator oluşturun ve bu ValueAnimator'ye, animasyon eklemek istediğiniz mülkün başlangıç ve bitiş değerlerini, animasyonun süresiyle birlikte girin. start() öğesini çağırdığınızda animasyon başlar. ValueAnimator, animasyonun tamamı boyunca animasyonun süresine ve geçen süreye göre 0 ile 1 arasında bir geçen süre oranı hesaplar. Geçen süre oranı, animasyon süresinin tamamlanma yüzdesini temsil eder. 0, %0, 1 ise %100 anlamına gelir. Örneğin, Şekil 1'de t = 10 ms'de geçen süre kesri 0,25 olur. Bunun nedeni, toplam sürenin t = 40 ms olmasıdır.

ValueAnimator, geçen kesri hesaplamayı tamamladığında ara kesri hesaplamak için şu anda ayarlanmış TimeInterpolator işlevini çağırır. Eşlenen kesirler, geçen kesri, ayarlanan zaman aralığını hesaba katan yeni bir keserle eşler. Örneğin, Şekil 2'de, animasyon yavaşça hızlandığı için interpolasyon oranı (yaklaşık 0,15) geçen kesir, 0,25, t = 10 ms'de. Şekil 1'de, interpolasyon kesir her zaman geçen kesir.

Interpolation fraction hesaplandığında ValueAnimator, animasyon yaptığınız mülkün değerini hesaplamak için interpolation fraction, başlangıç değeri ve animasyon bitiş değerine göre uygun TypeEvaluator işlevini çağırır. Örneğin, Şekil 2'de interpolasyon oranı 0,15, t = ise 10 ms .de, özelliğin o anki değeri 0,15 × (40 - 0) veya 6 olur.

Mülk animasyonunun görünüm animasyonundan farkı

Görünüm animasyon sistemi yalnızca View öğelerini animasyonlu hale getirme olanağı sunar. Bu nedenle, View olmayan öğeleri animasyonlu hale getirmek istiyorsanız bunu yapmak için kendi kodunuzu uygulamanız gerekir. Görünüm animasyon sistemi, View öğesinin yalnızca birkaç özelliğini (ör. görünümün ölçeklendirilmesi ve döndürülmesi) animasyonlu hale getirebilir. Arka plan rengi gibi özellikler animasyonlu hale getirilemez.

Görüntü animasyonu sisteminin bir diğer dezavantajı da, görüntünün kendisini değil, yalnızca çizildiği yeri değiştirmesidir. Örneğin, bir düğmeyi kullanmak için bir düğmeyi ekranda gördüğünüz şekilde, düğme doğru çiziliyor, ancak düğmeyi düğmesi değişmez; dolayısıyla, bunu işlemek için kendi mantığınızı uygulamanız gerekir.

Mülk animasyon sistemiyle bu kısıtlamalar tamamen kaldırılır ve herhangi bir nesnenin herhangi bir özelliğini (Görünümler ve Görünüm olmayanlar) animasyonlu hale getirebilirsiniz. Bu durumda, nesnenin kendisi de değiştirilir. Özellik animasyon sistemi, animasyonu yürütme açısından da daha sağlamdır. Kuyruklu a işareti bir üst düzeyde, animasyon oluşturmak istediğiniz özelliklere (örneğin, renk, ve interpolasyon gibi animasyonun çeşitli yönlerini tanımlayabilir. senkronizasyonuna yardımcı olur.

Ancak görüntüleme animasyonu sisteminin ayarlanması daha kısa sürer ve yazmak için daha az kod gerekir. Görüntüleme animasyonu, yapmanız gereken her şeyi yapıyorsa veya mevcut kodunuz zaten istiyorsanız, özellik animasyon sistemini kullanmanıza gerek yoktur. Ayrıca, kullanım alanı ortaya çıkarsa farklı durumlar için her iki animasyon sistemini de kullanmak mantıklı olabilir.

API'ye genel bakış

Mülk animasyon sisteminin API'lerinin çoğunu android.animation adresinde bulabilirsiniz. Görüntü animasyon sistemi android.view.animation'te zaten birçok interpolatör tanımladığından bu interpolatörleri mülk animasyon sisteminde de kullanabilirsiniz. Aşağıdaki tablolarda, kampanyalarınızın bileşenlerine göz atalım.

Animator sınıfı, içerik oluşturmak için temel yapıyı sağlar animasyonları da ekler. Bu sınıf, animasyonlu değerleri tam olarak desteklemek için genişletilmesi gereken yalnızca minimum işlevler sağladığından genellikle doğrudan kullanılmaz. Aşağıdaki alt sınıflar Animator'ü genişletir:

Tablo 1. Animasyoncular

Sınıf Açıklama
ValueAnimator Ayrıca, animasyona sahip olması gerekir. Animasyon değerlerini hesaplayan ve her animasyonun zamanlama ayrıntılarını, bir animasyonun tekrarlanıp tekrarlanmadığıyla ilgili bilgileri, güncelleme etkinlikleri alan dinleyicileri ve değerlendirilecek özel türleri ayarlama olanağını içeren tüm temel işlevlere sahiptir. Özellikleri animasyona dönüştürmenin iki parçası vardır: animasyonlu değerleri hesaplama ve bu değerleri animasyonlu nesne ve mülkte ayarlama. ValueAnimator ikinci parçayı çalmıyor, bu yüzden dinlemeniz gerekiyor ve ValueAnimator ve canlandırmak istediğiniz nesneleri kendi mantığınızla değiştirin. Bkz. Daha fazla bilgi için ValueAnimator ile animasyon oluşturma.
ObjectAnimator Hedef ayarlamanıza olanak tanıyan bir ValueAnimator alt sınıfı nesne ve nesne özelliklerini kontrol edin. Bu sınıf, aşağıdaki durumlarda mülkü uygun şekilde günceller: animasyon için yeni bir değer hesaplar. Şunu kullanmak için: ObjectAnimator, çoğu zaman çünkü hedef nesnelerde değer animasyonunu çok daha kolay hale getirir. Ancak, ObjectAnimator'un hedef nesnede belirli erişim yöntemlerinin bulunması gibi birkaç kısıtlaması daha olduğu için bazen doğrudan ValueAnimator kullanmak isteyebilirsiniz.
AnimatorSet Animasyonların belirli bir konumda çalıştırılması için bir grup mekanizması sağlar. güven içinde olur. Animasyonları birlikte, sırayla veya belirli bir gecikmeden sonra oynatacak şekilde ayarlayabilirsiniz. Daha fazla bilgi için Animasyon setleriyle birden fazla animasyon koordinasyonu yapma bölümüne bakın.

Değerlendiriciler, mülk animasyon sistemine belirli bir mülkle ilgili değerlerin nasıl hesaplanacağını söyler. Bu sınıflar, Animator sınıfı tarafından sağlanan zamanlama verilerini, animasyon başlangıç ve bitiş değerini alır ve bu verilere göre mülkün animasyonlu değerlerini hesaplar. Mülk animasyon sistemi aşağıdaki değerlendirme araçlarını sağlar:

Tablo 2. Değerlendirenler

Sınıf/Arayüz Açıklama
IntEvaluator int özelliklerinin değerlerini hesaplayan varsayılan değerlendirici.
FloatEvaluator float mülkleri için değerleri hesaplayan varsayılan değerlendirici.
ArgbEvaluator Temsil edilen renk özelliklerinin değerlerini hesaplamak için kullanılan varsayılan değerlendirici onaltılık değerler olarak gösterilir.
TypeEvaluator Kendi değerlendiricinizi oluşturmanıza olanak tanıyan arayüz. Bir int, float veya renk olmayan nesne özelliği nasıl kullanılacağını belirtmek için TypeEvaluator arayüzünü işlevini kullanın. Bu türleri varsayılan davranıştan farklı şekilde işlemek isterseniz int, float ve renk değerleri için özel bir TypeEvaluator de belirtebilirsiniz. Özel değerlendirici yazma hakkında daha fazla bilgi için TypeEvaluator kullanma bölümüne bakın.

Zaman interpolatörü, bir animasyondaki belirli değerlerin zaman fonksiyonu. Örneğin, animasyonların tüm animasyon boyunca doğrusal olarak gerçekleşmesini belirtebilirsiniz. Bu durumda animasyon, tüm süre boyunca eşit şekilde hareket eder. Alternatif olarak, animasyonların doğrusal olmayan bir zaman kullanmasını belirtebilirsiniz. Örneğin, animasyonun başında hızlanma ve animasyonun sonunda yavaşlama gibi. Tablo 3'te, android.view.animation içinde bulunan interpolasyon işlevleri açıklanmaktadır. Sağlanan interpolatörlerin hiçbiri uygun değilse TimeInterpolator arayüzünü uygulayın ve kendi arayüzünüzü oluşturun. Özel bir yorumlayıcı yazma hakkında daha fazla bilgi için Yorumlayıcıları kullanma başlıklı makaleyi inceleyin.

Tablo 3. Düzenleyiciler

Sınıf/Arabirim Açıklama
AccelerateDecelerateInterpolator Değişme hızı yavaş başlar ve biter ancak ortada hızlanır.
AccelerateInterpolator Değişim hızı yavaş başlayıp sonra başlayan bir interpolatör hızlanır.
AnticipateInterpolator Değişimi geriye başlayıp ileriye doğru ilerleyen bir interpolatör.
AnticipateOvershootInterpolator Değişimi geriye başlayıp ileri doğru fırlayan ve hedefi aşan bir interpolatör ve son olarak son değere geri döner.
BounceInterpolator Sonunda değişimi geri gelen bir interpolatör.
CycleInterpolator Animasyonu belirli sayıda döngü boyunca tekrar eden bir interpolatör.
DecelerateInterpolator Değişiklik hızı hızlı başlayıp yavaşlayan bir interpolatör.
LinearInterpolator Değişim hızı sabit olan bir interpolatör.
OvershootInterpolator Değişimi ileri sararak son değeri geçen bir interpolatör geri dönüyor.
TimeInterpolator Kendi interpolatörünüzü uygulamanıza olanak tanıyan bir arayüz.

ValueAnimator kullanarak animasyon oluşturma

ValueAnimator sınıfı, animasyon boyunca animasyon uygulanacak bir int, float veya renk değeri grubunu belirterek belirli bir türdeki değerleri animasyonlu hale getirmenize olanak tanır. Şu numaralardan birini arayarak ValueAnimator alabilirsiniz: fabrika yöntemleri: ofInt(), ofFloat() veya ofObject(). Örnek:

Kotlin

ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();

Bu kodda, ValueAnimator animasyonu, start() yöntemi çalıştırıldığında 1.000 ms'lik bir süreyle 0 ile 100 arasında bir değere ayarlanır.

Ayrıca, aşağıdakileri yaparak animasyon oluşturmak için özel bir tür de belirtebilirsiniz:

Kotlin

ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

Bu kodda, ValueAnimator animasyonu için, startPropertyValue ile endPropertyValue arasında mantık, start() yöntemi çalıştığında MyTypeEvaluator tarafından 1000 ms boyunca sağlanır.

Aşağıdaki kodda gösterildiği gibi ValueAnimator nesnesine bir AnimatorUpdateListener ekleyerek animasyon değerlerini kullanabilirsiniz:

Kotlin

ValueAnimator.ofObject(...).apply {
    ...
    addUpdateListener { updatedAnimation ->
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        textView.translationX = updatedAnimation.animatedValue as Float
    }
    ...
}

Java

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

onAnimationUpdate() yönteminde güncellenen animasyon değerine erişebilir ve bu değeri görünümlerinizden birinin bir mülkünde kullanabilirsiniz. Dinleyiciler hakkında daha fazla bilgi için Animasyon dinleyicileri bölümüne bakın.

ObjectAnimator'ı kullanarak animasyon yapma

ObjectAnimator, ValueAnimator sınıfının bir alt sınıfıdır (bir önceki bölümde açıklanmıştır) ve zamanlamayı birleştirir ValueAnimator için motor ve değer hesaplaması bir hedef nesnenin adlandırılmış özelliğine animasyon ekleme. Bu sayede, animasyonlu mülkün otomatik olarak güncellenmesi nedeniyle ValueAnimator.AnimatorUpdateListener öğesini uygulamanız gerekmediğinden herhangi bir nesneyi animasyonlu hale getirmek çok daha kolaydır.

ObjectAnimator oluşturma işlemi ValueAnimator oluşturmaya benzer ancak animasyon uygulanacak değerlerle birlikte nesneyi ve bu nesnenin mülkünün adını (dize olarak) da belirtirsiniz:

Kotlin

ObjectAnimator.ofFloat(textView, "translationX", 100f).apply {
    duration = 1000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
animation.setDuration(1000);
animation.start();

ObjectAnimator'ün mülkleri doğru şekilde güncellemesi için aşağıdakileri yapmanız gerekir:

  • Animasyon uyguladığınız nesne mülkünde, set<PropertyName>() biçiminde bir ayarlayıcı işlevi (bitişik ve ilk harfleri büyük olacak şekilde) olmalıdır. Çünkü ObjectAnimator animasyon sırasında özelliği otomatik olarak güncellediğinde, seçeceğim. Örneğin, tesis adı foo ise şunu yapmanız gerekir: setFoo() yöntemine sahip. Bu belirleyici yöntem yoksa üç tane seçenekler:
    • Yapma hakkınız varsa belirleyici yöntemini sınıfa ekleyin.
    • Değiştirme hakkına sahip olduğunuz bir sarmalayıcı sınıfı kullanın ve bu sarmalayıcının değerini geçerli bir setter yöntemiyle oluşturmalı ve bunu orijinal nesneye iletmelidir.
    • Bunun yerine ValueAnimator politikasını kullanın.
  • ObjectAnimator fabrika yöntemlerinden birinde values... parametresi için yalnızca bir değer belirtirseniz bunun animasyon ekler. Bu nedenle, canlandırdığınız nesne özelliğinin bir alıcı işlevi olmalıdır. animasyonun başlangıç değerini elde etmek için kullanılan bir değerdir. Alıcı işlevi get<PropertyName>() biçiminde olmalıdır. Örneğin, mülk adı foo ise getFoo() yönteminiz olmalıdır.
  • Animasyon uyguladığınız mülkün alıcı (gerekirse) ve ayarlayıcı yöntemleri, ObjectAnimator için belirttiğiniz başlangıç ve bitiş değerleriyle aynı türde çalışmalıdır. Örneğin, targetObject.setPropName(float) targetObject.getPropName() aşağıdaki ObjectAnimator öğesini oluşturursanız:
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • Animasyon uyguladığınız mülke veya nesneye bağlı olarak, ekranı güncellenmiş animasyonlu değerlerle yeniden çizmeye zorlamak için bir Görünüm'de invalidate() yöntemini çağırmanız gerekebilir. Bunu onAnimationUpdate() callback'inde yaparsınız. Örneğin, bir Çizilebilir nesnenin renk özelliğini canlandırmak, yalnızca yeniden çizmeye başlar. View'daki mülk belirleyicilerin tümü, örneğin setAlpha() setTranslationX() görünümü uygun şekilde geçersiz kılar, dolayısıyla bu öğeleri çağırırken Görünümü geçersiz kılmanıza gerek kalmaz yöntemlerine yer verir. Dinleyiciler hakkında daha fazla bilgi için Animasyon dinleyicileri bölümüne bakın.

AnimatorSet kullanarak birden fazla animasyon koreografisi oluşturma

Çoğu durumda, başka bir animasyonun ne zaman başladığına veya bittiğine bağlı olarak bir animasyon oynatmak istersiniz. Android sistemi, animasyonlarınızı bir AnimatorSet içinde gruplandırmanıza olanak tanır. Böylece animasyonların aynı anda, sırayla veya belirli bir gecikmeden sonra başlatılıp başlatılmayacağını belirtebilirsiniz. Ayrıca AnimatorSet nesneleri iç içe yerleştirebilirsiniz.

Aşağıdaki kod snippet'inde, aşağıdaki Animator nesneleri aşağıdaki şekilde oynatılır:

  1. bounceAnim çalınıyor.
  2. squashAnim1, squashAnim2, stretchAnim1 ve stretchAnim2'i aynı anda oynatıyor.
  3. bounceBackAnim çalınıyor.
  4. fadeAnim çalınıyor.

Kotlin

val bouncer = AnimatorSet().apply {
    play(bounceAnim).before(squashAnim1)
    play(squashAnim1).with(squashAnim2)
    play(squashAnim1).with(stretchAnim1)
    play(squashAnim1).with(stretchAnim2)
    play(bounceBackAnim).after(stretchAnim2)
}
val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
}
AnimatorSet().apply {
    play(bouncer).before(fadeAnim)
    start()
}

Java

AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

Animasyon dinleyicileri

Aşağıda açıklanan dinleyicilerle, animasyon süresince önemli etkinlikleri dinleyebilirsiniz.

  • Animator.AnimatorListener
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate(): Animasyonun her karesinde çağrılır. Animasyon sırasında ValueAnimator tarafından oluşturulan hesaplanmış değerleri kullanmak için bu etkinliği dinleyin. Değeri kullanmak için getAnimatedValue() yöntemiyle etkinliğe iletilen ValueAnimator nesnesini sorgulayıp mevcut animasyonlu değeri alın. Bunu uygulamak ValueAnimator kullanıyorsanız işleyici gerekir.

      Canlandırmakta olduğunuz özellik veya nesneye bağlı olarak, invalidate() seçeneğini kullanarak yeni animasyonlu değerlerle kendisini yeniden çizecek. Örneğin, bir Çekilebilir nesnenin renk özelliği, yalnızca söz konusu nesne bu nesnede ekranda güncellemelere neden yeniden çizer. Görünümdeki tüm özellik ayarlayıcılar (ör. setAlpha() ve setTranslationX()) görünümü doğru şekilde geçersiz kılar. Bu nedenle, bu yöntemleri yeni değerlerle çağırırken görünümü geçersiz kılmanız gerekmez.

Animator.AnimatorListener arayüzünün tüm yöntemlerini uygulamak istemiyorsanız Animator.AnimatorListener arayüzünü uygulamak yerine AnimatorListenerAdapter sınıfını genişletebilirsiniz. AnimatorListenerAdapter sınıfı, geçersiz kılmayı seçebileceğiniz yöntemlerin boş uygulamalarını sağlar.

Örneğin, aşağıdaki kod snippet'i bir AnimatorListenerAdapter oluşturur yalnızca onAnimationEnd() için geri arama:

Kotlin

ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            balls.remove((animation as ObjectAnimator).target)
        }
    })
}

Java

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

ViewGroup nesnelerinde yapılan düzen değişikliklerini canlandırma

Mülk animasyon sistemi, ViewGroup nesnelerindeki değişiklikleri animasyonlu hale getirmenin yanı sıra View nesnelerini animasyonlu hale getirmenin kolay bir yolunu sunar.

ViewGroup içindeki düzen değişikliklerini LayoutTransition sınıf. Bir ViewGroup'a eklediğiniz veya ViewGroup'dan kaldırdığınız görünümler ya da bir görünümün VISIBLE, INVISIBLE veya GONE ile setVisibility() yöntemini çağırdığınız görünümler görünme ve kaybolma animasyonu geçirebilir. ViewGroup'daki kalan görünümler, görünüm eklediğinizde veya kaldırdığınızda yeni konumlarına animasyonlu olarak da gidebilir. Anahtar kelimelerin bir LayoutTransition nesnesinde aşağıdaki animasyonlar setAnimator() numaralı telefonu arayarak Animator nesnesini aşağıdaki LayoutTransition sabit değer:

  • APPEARING - Aynı öğede bulunan öğelerde çalıştırılan animasyonu belirten görünür.
  • CHANGE_APPEARING: Kapsayıcıda görünen yeni bir öğe nedeniyle değişen öğelerde çalıştırılan animasyonu belirten bir işaret.
  • DISAPPEARING: Kapsayıcıdan kaybolan öğelerde oynatılan animasyonu belirten bir işaret.
  • CHANGE_DISAPPEARING: Bir öğenin kapsayıcıdan kaybolması nedeniyle değişen öğelerde çalıştırılan animasyonu gösteren bir işaret.

Bu dört etkinlik türü için kendi özel animasyonlarınızı tanımlayarak sayfa düzeni geçişlerinizin görünümünü özelleştirebilir veya animasyon sistemine varsayılan animasyonları kullanmasını söyleyebilirsiniz.

ViewGroup için android:animateLayoutchanges özelliğini true olarak ayarlamak üzere aşağıdakileri yapın:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

Bu özelliği true olarak ayarladığınızda, ViewGroup'a eklenen veya ViewGroup'dan kaldırılan View'ların yanı sıra ViewGroup'daki diğer View'lar otomatik olarak animasyonlu hale gelir.

StateListAnimator'ı kullanarak görünüm durumu değişikliklerini canlandırma

StateListAnimator sınıfı, bir görünümün durumu değiştiğinde çalışan animatörleri tanımlamanıza olanak tanır. Bu nesne, bir Animator nesnesi çağrılır ve görünüm durumundaki (ör. "basılmış" veya "odaklanmış") değişiklikler.

StateListAnimator, bir XML kaynağında kök <selector> öğesi ve her biri StateListAnimator sınıfı tarafından tanımlanan farklı bir görüntüleme durumunu belirten alt <item> öğeleriyle tanımlanabilir. Her biri <item>, bir özellik animasyonu grubunun tanımını içerir.

Örneğin, aşağıdaki dosya, basıldığında görünümün x ve y ölçeğini değiştiren bir durum listesi animatörü oluşturur:

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the pressed state; increase x and y size to 150% -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
        </set>
    </item>
    <!-- the default, non-pressed state; set x and y size to 100% -->
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
        </set>
    </item>
</selector>

Bir görünüme durum listesi animatörü eklemek için android:stateListAnimator özelliğini aşağıdaki gibi tanımlar:

<Button android:stateListAnimator="@xml/animate_scale"
        ... />

Artık animate_scale.xml işlevinde tanımlanan animasyonlar, bu düğmenin kullanabilirsiniz.

Bunun yerine, kodunuzdaki bir görünüme durum listesi animatörü atamak için AnimatorInflater.loadStateListAnimator() yöntemini kullanın ve animatörü View.setStateListAnimator() yöntemiyle görünümünüze atayın.

Dilerseniz görünümün özelliklerini animasyonla oluşturmak yerine, AnimatedStateListDrawable kullanarak durum değişiklikleri hakkında bilgi edinin. Widget'lardaki bazı sistem widget'ları Android 5.0, varsayılan olarak bu animasyonları kullanır. Aşağıdaki örnekte, AnimatedStateListDrawable öğesinin XML kaynağı olarak nasıl tanımlanacağı gösterilmektedir:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

TypeEvaluator kullanma

Android sisteminde bilinmeyen bir türü animasyonlu hale getirmek istiyorsanız TypeEvaluator arayüzünü uygulayarak kendi değerlendiricinizi oluşturabilirsiniz. Android sistemi tarafından bilinen türler int, float veya bir renktir. Bunlar IntEvaluator, FloatEvaluator ve ArgbEvaluator tür değerlendiricileri tarafından desteklenir.

TypeEvaluator kampanyasında uygulanacak yalnızca bir yöntem vardır. arayüzü, evaluate() yöntemi. Bu da animasyonlu mülkünüz için uygun bir değeri döndürmek amacıyla animasyonun geçerli noktasını seçin. FloatEvaluator sınıfında bunun nasıl yapılacağı gösterilmektedir:

Kotlin

private class FloatEvaluator : TypeEvaluator<Any> {

    override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any {
        return (startValue as Number).toFloat().let { startFloat ->
            startFloat + fraction * ((endValue as Number).toFloat() - startFloat)
        }
    }

}

Java

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

Not: ValueAnimator (veya ObjectAnimator) işlevi çalıştırıldığında, animasyondaki mevcut geçen süre kesri (0 ile 1 arasında bir değer) hesaplanır ve ardından kullandığınız interpolatöre bağlı olarak bu değerin bir ara değerle doldurulmuş sürümü hesaplanır. İnterpolasyon oranı, TypeEvaluator metriğinizin fraction parametresi üzerinden aldığı değerdir. Dolayısıyla, Animasyonlu değerleri hesaplarken ara değer hesaplamasını dikkate almak zorunda değildir.

İnterpolatör kullanma

Bir interpolatör, animasyondaki belirli değerlerin zamana göre nasıl hesaplanacağını tanımlar. Örneğin, animasyonların tüm animasyon boyunca doğrusal olarak gerçekleşmesini belirtebilirsiniz. Bu durumda animasyon, tüm süre boyunca eşit şekilde hareket eder. Animasyonların doğrusal olmayan zaman kullanmasını da belirtebilirsiniz. Örneğin, animasyonun başında veya sonunda hızlanma ya da yavaşlama kullanabilirsiniz.

Animasyon sistemindeki interpolatörler, animatörlerden geçen süreyi ifade eder. İnterpolatörler bu kesri, istenilen türe denk gelecek şekilde değiştirir animasyon içerir. Android sistemi, Google Analytics 4'te tarama yapmak için android.view.animation package. Bunların hiçbiri TimeInterpolator arayüzünü uygulayabilir ve kendi özel talep sahip.

Örneğin, varsayılan interpolatör AccelerateDecelerateInterpolator ve LinearInterpolator, interpolasyonlu kesirleri nasıl hesapladığı aşağıda karşılaştırılmıştır. LinearInterpolator metriğinin, geçen kesir üzerinde herhangi bir etkisi yoktur. AccelerateDecelerateInterpolator, animasyona doğru hızlanır ve animasyondan çıkarken yavaşlar. Aşağıdaki yöntemler bu interpolatörlerin mantığını tanımlar:

AccelerateDecelerateInterpolator

Kotlin

override fun getInterpolation(input: Float): Float =
        (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f

Java

@Override
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

Doğrusal İnterpolator

Kotlin

override fun getInterpolation(input: Float): Float = input

Java

@Override
public float getInterpolation(float input) {
    return input;
}

Aşağıdaki tabloda, bu sinyaller ile hesaplanan yaklaşık değerler gösterilmektedir 1.000 ms süren bir animasyon için arapolatörler:

ms geçti Geçen süre kesri/Değerlendirilen kesir (Doğrusal) Eşlenen kesir (Hızlandır/Yavaşla)
0 0 0
200 0,2 0,1
400 0,4 0,345
600 .6 0,654
800 0,8 .9
1000 1 1

Tabloda gösterildiği gibi, LinearInterpolator değerleri aynı hızda değiştirir. Geçen her 200 ms için 0,2 değerini alır. AccelerateDecelerateInterpolator, 200 ms ile 600 ms arasında değerleri LinearInterpolator'ten daha hızlı, 600 ms ile 1000 ms arasında ise daha yavaş değiştirir.

Animasyon karelerini belirleme

Keyframe nesnesi, bir animasyonun belirli bir zamanında belirli bir durumu tanımlamanıza olanak tanıyan bir zaman/değer çiftinden oluşur. Her animasyon karesinin kendi karesi de olabilir animasyonun önceki aralıktaki aralıkta davranışını kontrol etmek için arapolatör bu animasyon karesinin zamanını ve zamanını değiştirebilirsiniz.

Bir Keyframe nesnesini örneklendirmek için fabrikadan birini kullanmanız gerekir. yöntemleri, ofInt(), ofFloat() veya ofObject() yöntemini kullanarak uygun Keyframe türünü elde edin. Ardından, PropertyValuesHolder nesnesi elde etmek için ofKeyframe() fabrika yöntemini çağırırsınız. Nesneyi aldıktan sonra, PropertyValuesHolder nesnesini ve animasyonlandırılacak nesneyi ileterek bir animatör elde edebilirsiniz. Aşağıdaki kod snippet'inde bunun nasıl yapılacağı gösterilmektedir:

Kotlin

val kf0 = Keyframe.ofFloat(0f, 0f)
val kf1 = Keyframe.ofFloat(.5f, 360f)
val kf2 = Keyframe.ofFloat(1f, 0f)
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2)
ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply {
    duration = 5000
}

Java

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

Görüntülemelerin animasyonu

Mülk animasyon sistemi, görüntüleme nesnelerinin kolayca animasyonlandırılmasına olanak tanır ve görüntüleme animasyon sistemine kıyasla birkaç avantaj sunar. Görünüm animasyon sistemi, nesneleri çizilme biçimini değiştirerek View nesnelerini dönüştürdü. Bu görünümün değiştirilebilecek herhangi bir özelliği olmadığından, her bir Görünümün kapsayıcısında işlenebilir. Bu durum, Görünüm canlandırmasına neden olmuş ancak Görünüm nesnesinde herhangi bir değişikliğe neden olmamıştır. Bu Bu durum, bir nesnenin orijinal konumunda hâlâ var olmasına rağmen hâlâ bulunduğu gibi bir davranışa yol açmıştır. ekranda farklı bir yere çizilmiş olabilir. Android 3.0'ta bu dezavantajı ortadan kaldırmak için yeni özellikler ve bunlara karşılık gelen alıcı ve ayarlayıcı yöntemleri eklendi.

Mülk animasyon sistemi, görünüm nesnelerindeki gerçek özellikleri değiştirerek ekrandaki görünümleri canlandırabilir. İçinde Ayrıca, Görünümler invalidate() öğesini de otomatik olarak yöntemini kullanmanızı öneririz. View sınıfındaki, mülk animasyonlarını kolaylaştıran yeni özellikler şunlardır:

  • translationX ve translationY: Bu özellikler, görünümün sol ve üst koordinatlarından bir delta olarak konumunu kontrol eder. Bu koordinatlar, görünümün düzen kapsayıcısı tarafından belirlenir.
  • rotation, rotationX ve rotationY: Bu özellikler, pivot noktasının etrafında 2D (rotation özelliği) ve 3D rotasyonu kontrol eder.
  • scaleX ve scaleY: Bu mülkler, bir görünümün pivot noktası etrafındaki 2D ölçeklendirmesini kontrol eder.
  • pivotX ve pivotY: Bu özellikler, etrafında döndürme ve ölçeklendirme dönüşümlerinin gerçekleştiği pivot noktası. Varsayılan olarak, pivot noktası nesnenin ortasında bulunur.
  • x ve y: Bunlar, Görünümün kapsayıcısındaki nihai konumunu, sol ve üst değerlerin ve translationX ile translationY değerlerinin toplamı olarak tanımlayan basit yardımcı mülkleridir.
  • alpha: Görünümdeki alfa şeffaflığını temsil eder. Bu değer 1'dir (opak) varsayılan olarak 0 değeri tam şeffaflığı temsil eder (görünmez).

Bir Görünüm nesnesinin rengi veya döndürme değeri gibi bir özelliğine animasyon eklemek için bir özellik animatörü oluşturup istediğiniz Görünüm özelliğini animasyon içerir. Örnek:

Kotlin

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)

Java

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

Animasyon oluşturucu oluşturma hakkında daha fazla bilgi için ValueAnimator ve ObjectAnimator ile animasyon oluşturma bölümlerine bakın.

ViewPropertyAnimator'ı kullanarak animasyon oluşturma

ViewPropertyAnimator, çeşitli animasyonlar için basit bir yol sağlar tek bir temel Animator kullanarak paralel olarak View özellikleri nesnesini tanımlayın. ObjectAnimator gibi davranır çünkü görünüm özelliklerinin gerçek değerlerine bakar ancak aynı zamanda birçok mülk için animasyon bir kez. Ayrıca, ViewPropertyAnimator kullanma kodu çok daha kısa ve okunması daha kolaydır. Aşağıdaki kod snippet'leri, bir görünümün x ve y özelliğini aynı anda animasyonla değiştirirken birden fazla ObjectAnimator nesnesi, tek bir ObjectAnimator ve ViewPropertyAnimator kullanmanın farklılıklarını gösterir.

Multiple ObjectAnimator nesneleri

Kotlin

val animX = ObjectAnimator.ofFloat(myView, "x", 50f)
val animY = ObjectAnimator.ofFloat(myView, "y", 100f)
AnimatorSet().apply {
    playTogether(animX, animY)
    start()
}

Java

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

One ObjectAnimator

Kotlin

val pvhX = PropertyValuesHolder.ofFloat("x", 50f)
val pvhY = PropertyValuesHolder.ofFloat("y", 100f)
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()

Java

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

ViewPropertyAnimator

Kotlin

myView.animate().x(50f).y(100f)

Java

myView.animate().x(50f).y(100f);

ViewPropertyAnimator hakkında daha ayrıntılı bilgi için ilgili Android Developers blog yayınını inceleyin.

Animasyonları XML'de tanımlama

Mülk animasyonu sistemi, mülk animasyonlarını programatik olarak belirtmek yerine XML ile belirtmenize olanak tanır. Animasyonlarınızı XML'de tanımlayarak animasyonlarınızı birden fazla etkinlikte kolayca yeniden kullanabilir ve animasyon sırasını daha kolay düzenleyebilirsiniz.

Yeni mülk animasyon API'lerini kullanan animasyon dosyalarını eski view animasyonlu çerçevesi, Android 3.1'den itibaren, özellik animasyonlarına ilişkin XML dosyalarını res/animator/ dizinine kaydetmeniz gerekir.

Aşağıdaki mülk animasyon sınıfları, aşağıdaki XML etiketleriyle XML beyanı desteğine sahiptir:

XML bildiriminizde kullanabileceğiniz özellikleri bulmak için Animasyon kaynaklar bölümüne göz atın. Aşağıdaki örnekte iki nesne animasyonu grubu oynatılır Buna göre, iç içe yerleştirilmiş ilk grup iki nesne animasyonunu birlikte oynatır:

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>

Bu animasyonu çalıştırmak için kodunuzdaki XML kaynaklarını bir AnimatorSet nesnesine şişirmeniz ve ardından animasyon grubunu başlatmadan önce tüm animasyonlar için hedef nesneleri ayarlamanız gerekir. setTarget() çağrısı yapıldığında, kolaylık sağlamak amacıyla AnimatorSet öğesinin tüm alt öğeleri için tek bir hedef nesne ayarlanır. Aşağıdaki kodda bunun nasıl yapılacağı gösterilmektedir:

Kotlin

(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply {
    setTarget(myObject)
    start()
}

Java

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animator.property_animator);
set.setTarget(myObject);
set.start();

XML'de bir ValueAnimator öğesini de aşağıdaki örnekte gösterilmektedir:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0f"
    android:valueTo="-100f" />

Kodunuzda önceki ValueAnimator öğesini kullanmak için bir AnimatorUpdateListener, güncellenmiş animasyon değerini alıp görünümlerinizden birinin bir mülkünde kullanın, aşağıdaki kodda gösterildiği gibidir:

Kotlin

(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply {
    addUpdateListener { updatedAnimation ->
        textView.translationX = updatedAnimation.animatedValue as Float
    }

    start()
}

Java

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,
        R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

xmlAnimator.start();

Özellik animasyonlarını tanımlamaya yönelik XML söz dizimi hakkında bilgi için Animasyon kaynaklar bölümüne göz atın.

Kullanıcı arayüzü performansı üzerindeki olası etkiler

Kullanıcı arayüzünü güncelleyen animatörler, her kare için fazladan oluşturma işine neden olur. reklam öğesidir. Bu nedenle, kaynakların yoğun bir şekilde kullanıldığı animasyonlar uygulamanızın performansını olumsuz yönde etkileyebilir.

Kullanıcı arayüzünüzü animasyonlu hale getirmek için gereken çalışmalar, oluşturma ardışık düzeninin animasyon aşamasına eklenir. Profil GPU oluşturma özelliğini etkinleştirip animasyon aşamasını izleyerek animasyonlarınızın uygulamanızın performansını etkileyip etkilemediğini öğrenebilirsiniz. Daha fazla bilgi için Profil GPU oluşturma adım adım başlıklı makaleyi inceleyin.