Mülk Animasyonuna Genel Bakış

Compose yöntemini deneyin
Jetpack Compose, Android için önerilen kullanıcı arayüzü araç setidir. Compose'da animasyonları nasıl kullanacağınızı öğrenin.

Mülk animasyonu sistemi, neredeyse her şeyi animasyon hâline getirmenize olanak tanıyan sağlam bir çerçevedir. Ekrana çizilip çizilmediğine bakılmaksızın, herhangi bir nesne özelliğini zaman içinde değiştirecek bir animasyon tanımlayabilirsiniz. Özellik animasyonu, bir özelliğin (nesnedeki bir alan) değerini belirli bir süre içinde değiştirir. Bir öğeye animasyon eklemek için animasyon eklemek istediğiniz nesne özelliğini (ör. nesnenin ekrandaki konumu), animasyonun ne kadar süreceğini ve hangi değerler arasında animasyon eklemek istediğinizi belirtirsiniz.

Özellik animasyonu sistemi, bir animasyonun aşağıdaki özelliklerini tanımlamanıza olanak tanır:

  • Süre: Animasyonun süresini belirtebilirsiniz. Varsayılan uzunluk 300 ms'dir.
  • Zaman enterpolasyonu: Özelliğin değerlerinin, animasyonun geçerli geçen süresinin bir fonksiyonu olarak nasıl hesaplanacağını belirtebilirsiniz.
  • Tekrar sayısı ve davranışı: Animasyonun bir sürenin sonuna ulaştığında tekrarlanıp tekrarlanmayacağını ve kaç kez tekrarlanacağını belirtebilirsiniz. Ayrıca animasyonun tersten oynatılmasını isteyip istemediğinizi de belirtebilirsiniz. Tersine ayarlandığında animasyon, tekrar sayısı tamamlanana kadar tekrar tekrar ileri ve geri oynatılır.
  • Animator setleri: Animasyonları birlikte, sırayla veya belirli gecikmelerden sonra oynatılan mantıksal setler halinde gruplandırabilirsiniz.
  • Kare yenileme gecikmesi: Animasyonunuzun karelerinin ne sıklıkta yenileneceğini belirleyebilirsiniz. Varsayılan olarak 10 ms'de bir yenileme ayarlanır ancak uygulamanızın kareleri yenileyebileceği hız, nihayetinde sistemin genel olarak ne kadar meşgul olduğuna ve sistemin temel zamanlayıcıya ne kadar hızlı hizmet verebileceğine bağlıdır.

Özellik animasyonunun tam örneğini görmek için GitHub'daki CustomTransition örneğindeki ChangeColor sınıfına bakın.

Mülk animasyonunun işleyiş şekli

Öncelikle, basit bir örnekle animasyonun nasıl çalıştığını inceleyelim. Şekil 1'de, ekrandaki yatay konumunu temsil eden x özelliğiyle animasyon oluşturulmuş varsayımsal bir nesne gösterilmektedir. Animasyonun süresi 40 ms, hareket edilecek mesafe ise 40 piksel olarak ayarlanır. Varsayılan kare yenileme hızı olan her 10 ms'de nesne yatay olarak 10 piksel hareket eder. 40 ms'nin sonunda animasyon durur ve nesne 40 yatay konumunda sonlanır. Bu, doğrusal enterpolasyonlu bir animasyon örneğidir. Bu animasyonda nesne sabit bir hızda hareket eder.

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

Ayrıca, doğrusal olmayan bir enterpolasyona sahip olacak animasyonlar da belirtebilirsiniz. Şekil 2, animasyonun başında hızlanan ve sonunda yavaşlayan varsayımsal bir nesneyi gösterir. Nesne, 40 ms içinde 40 piksel hareket etmeye devam eder ancak doğrusal olmayan bir şekilde hareket eder. 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, ortadakinden daha azdır.

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

Özellik animasyonu sisteminin önemli bileşenlerinin, yukarıda gösterilen animasyonları nasıl hesapladığına ayrıntılı olarak bakalım. Şekil 3'te ana sınıfların birbirleriyle nasıl çalıştığı gösterilmektedir.

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

ValueAnimator nesnesi, animasyonun ne kadar süredir çalıştığı ve animasyonun geçerli özellik değeri gibi animasyonunuzun zamanlamasını takip eder.

ValueAnimator, animasyon enterpolasyonunu tanımlayan bir TimeInterpolator ve animasyon uygulanan özelliğin değerlerinin nasıl hesaplanacağını tanımlayan bir TypeEvaluator öğesini kapsar. Örneğin, Şekil 2'de kullanılan TimeInterpolator, AccelerateDecelerateInterpolator olur ve TypeEvaluator, IntEvaluator olur.

Animasyon başlatmak için bir ValueAnimator oluşturun ve animasyon eklemek istediğiniz özelliğin başlangıç ve bitiş değerlerini, animasyonun süresiyle birlikte girin. start()'ı aradığınızda animasyon başlar. Animasyonun tamamı boyunca ValueAnimator, animasyonun süresine ve ne kadar zaman geçtiğine bağlı olarak 0 ile 1 arasında bir geçen süre oranı hesaplar. Geçen süre oranı, animasyonun tamamlanma yüzdesini gösterir. 0 değeri %0, 1 değeri ise %100 anlamına gelir. Örneğin, Şekil 1'de t = 10 ms'de geçen süre oranı 0,25 olur .Bunun nedeni, toplam sürenin t = 40 ms olmasıdır.

ValueAnimator, geçen sürenin kesirini hesaplamayı bitirdiğinde, şu anda ayarlanmış olan TimeInterpolator'u çağırarak interpolasyonlu kesir hesaplar. İnterpolasyonlu bir kesir, geçen kesri, ayarlanan zaman interpolasyonunu dikkate alan yeni bir kesirle eşler. Örneğin, Şekil 2'de animasyon yavaşça hızlandığı için ara değer olarak elde edilen kesir (yaklaşık 0,15), t = 10 ms'de geçen kesirden (0,25) küçüktür. Şekil 1'de ara değer olarak elde edilen kesir her zaman geçen kesirle aynıdır.

İnterpolasyonlu kesir hesaplandığında ValueAnimator, animasyonunu yaptığınız özelliğin değerini hesaplamak için uygun TypeEvaluator işlevini çağırır. Bu hesaplama, interpolasyonlu kesir, başlangıç değeri ve animasyonun bitiş değerine göre yapılır. Örneğin, Şekil 2'de, t = 10 ms iken enterpolasyonlu kesir 0,15'tir. Bu nedenle, o sırada özelliğin değeri 0,15 × (40 - 0) veya 6 olur.

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

Görünüm animasyonu sistemi yalnızca View nesneleri canlandırma özelliği sunar. Bu nedenle, View olmayan nesneleri canlandırmak istiyorsanız bunu yapmak için kendi kodunuzu uygulamanız gerekir. Görünüm animasyonu sistemi, View nesnesinin yalnızca birkaç yönünü (ör. bir görünümün ölçeklendirilmesi ve döndürülmesi, ancak arka plan rengi değil) animasyon için kullanıma sunması nedeniyle de sınırlıdır.

Görünüm animasyonu sisteminin bir diğer dezavantajı ise yalnızca Görünüm'ün çizildiği yeri değiştirmesi ve Görünüm'ün kendisini değiştirmemesidir. Örneğin, bir düğmeyi ekranda hareket edecek şekilde animasyonlandırdıysanız düğme doğru şekilde çizilir ancak düğmeyi tıklayabileceğiniz gerçek konum değişmez. Bu nedenle, bunu işlemek için kendi mantığınızı uygulamanız gerekir.

Özellik animasyonu sistemiyle bu kısıtlamalar tamamen kaldırılır ve herhangi bir nesnenin (görünümler ve görünüm olmayanlar) herhangi bir özelliğini canlandırabilirsiniz. Nesnenin kendisi de gerçekten değiştirilir. Mülk animasyonu sistemi, animasyonu gerçekleştirme konusunda da daha sağlamdır. Genel olarak, animasyoncuları renk, konum veya boyut gibi animasyon eklemek istediğiniz özelliklere atar ve animasyonun enterpolasyon ve birden fazla animasyoncunun senkronizasyonu gibi yönlerini tanımlayabilirsiniz.

Ancak görünüm animasyonu sisteminin kurulumu daha kısa sürer ve daha az kod yazmayı gerektirir. Görünüm animasyonu, yapmanız gereken her şeyi yapıyorsa veya mevcut kodunuz zaten istediğiniz şekilde çalışıyorsa özellik animasyonu sistemini kullanmanız gerekmez. Kullanım alanı ortaya çıkarsa farklı durumlar için her iki animasyon sistemini de kullanmak mantıklı olabilir.

API'ye genel bakış

Mülk animasyonu sisteminin API'lerinin çoğunu android.animation bölümünde bulabilirsiniz. Görünüm animasyonu sistemi android.view.animation içinde birçok interpolasyon fonksiyonunu tanımladığından bu interpolasyon fonksiyonlarını özellik animasyonu sisteminde de kullanabilirsiniz. Aşağıdaki tablolarda, özellik animasyonu sisteminin ana bileşenleri açıklanmaktadır.

Animator sınıfı, animasyon oluşturmak için temel yapıyı sağlar. Bu sınıf, değerlerin animasyonunu tam olarak desteklemek için genişletilmesi gereken minimum işlevselliği sağladığından genellikle doğrudan kullanılmaz. Aşağıdaki alt sınıflar Animator sınıfını genişletir:

Tablo 1. Animatörler

Sınıf Açıklama
ValueAnimator Özellik animasyonunun ana zamanlama motoru. Animasyon uygulanacak özelliğin değerlerini de hesaplar. Animasyon değerlerini hesaplayan tüm temel işlevlere sahiptir ve her animasyonun zamanlama ayrıntılarını, animasyonun tekrarlanıp tekrarlanmadığıyla ilgili bilgileri, güncelleme etkinliklerini alan dinleyicileri ve değerlendirilecek özel türleri ayarlama olanağını içerir. Özellikleri canlandırmak için iki adım vardır: animasyonlu değerleri hesaplama ve bu değerleri, animasyon uygulanan nesne ve özellik üzerinde ayarlama. ValueAnimator ikinci kısmı gerçekleştirmez. Bu nedenle, ValueAnimator tarafından hesaplanan değerlerdeki güncellemeleri dinlemeniz ve kendi mantığınızla animasyon eklemek istediğiniz nesneleri değiştirmeniz gerekir. Daha fazla bilgi için ValueAnimator ile animasyon oluşturma bölümüne bakın.
ObjectAnimator Animasyon eklemek için hedef nesne ve nesne özelliği ayarlamanıza olanak tanıyan ValueAnimator alt sınıfı. Bu sınıf, animasyon için yeni bir değer hesapladığında özelliği buna göre günceller. Hedef nesnelerdeki değerleri animasyonla gösterme sürecini çok daha kolay hale getirdiği için ObjectAnimator'yı çoğu zaman kullanmak istersiniz. Ancak, ObjectAnimator hedef nesnede belirli erişimci yöntemlerinin bulunmasını gerektirmek gibi birkaç kısıtlamaya daha sahip olduğundan bazen doğrudan ValueAnimator kullanmak isteyebilirsiniz.
AnimatorSet Animasyonları birbirleriyle ilişkili olarak çalışacak şekilde gruplandırmak için bir mekanizma sağlar. Animasyonları birlikte, sırayla veya belirli bir gecikmeyle oynatılacak şekilde ayarlayabilirsiniz. Daha fazla bilgi için Animator Kümeleri ile birden fazla animasyonu koreografiye etme bölümüne bakın.

Değerlendiriciler, özellik animasyon sistemine belirli bir özelliğin değerlerinin nasıl hesaplanacağını söyler. Animator sınıfı tarafından sağlanan zamanlama verilerini, animasyonun başlangıç ve bitiş değerini alır ve bu verilere göre özelliğin animasyonlu değerlerini hesaplar. Özellik animasyonu sistemi aşağıdaki değerlendiricileri sağlar:

Tablo 2. Değerlendiriciler

Sınıf/Arayüz Açıklama
IntEvaluator int özelliklerinin değerlerini hesaplamak için kullanılan varsayılan değerlendirici.
FloatEvaluator float özelliklerinin değerlerini hesaplamak için kullanılan varsayılan değerlendirici.
ArgbEvaluator Onaltılık değerler olarak gösterilen renk özelliklerinin değerlerini hesaplamak için kullanılan varsayılan değerlendirici.
TypeEvaluator Kendi değerlendiricinizi oluşturmanıza olanak tanıyan bir arayüz. int, float veya renk olmayan bir nesne özelliğine animasyon uyguluyorsanız nesne özelliğinin animasyonlu değerlerinin nasıl hesaplanacağını belirtmek için TypeEvaluator arayüzünü uygulamanız gerekir. Bu türleri varsayılan davranıştan farklı şekilde işlemek istiyorsanız 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 interpolasyonu, animasyondaki belirli değerlerin zamanın bir fonksiyonu olarak nasıl hesaplandığını tanımlar. Örneğin, animasyonların tüm animasyon boyunca doğrusal olarak gerçekleşmesini (yani animasyonun tüm süre boyunca eşit şekilde hareket etmesini) belirtebilir veya animasyonların doğrusal olmayan zaman kullanmasını (ör. animasyonun başında hızlanıp sonunda yavaşlamasını) belirtebilirsiniz. Tablo 3'te, android.view.animation içinde bulunan interpolasyon fonksiyonları açıklanmaktadır. Sağlanan interpolasyonlardan hiçbiri ihtiyaçlarınıza uygun değilse TimeInterpolator arayüzünü uygulayın ve kendi interpolasyonunuzu oluşturun. Özel bir interpolasyon işlevi yazma hakkında daha fazla bilgi için İnterpolasyon işlevlerini kullanma başlıklı makaleyi inceleyin.

Tablo 3. İnterpolasyonlar

Sınıf/Arayüz Açıklama
AccelerateDecelerateInterpolator Değişim hızı yavaş başlayıp yavaş biten ancak ortada hızlanan bir interpolatör.
AccelerateInterpolator Değişim hızı yavaş başlayıp hızlanan bir interpolatör.
AnticipateInterpolator Değişikliği önce geriye doğru başlayıp sonra ileriye doğru fırlayan bir interpolatör.
AnticipateOvershootInterpolator Değişimi geriye doğru başlayan, ileriye doğru fırlayan ve hedef değeri aşan, ardından nihai değere geri dönen bir interpolatör.
BounceInterpolator Değişikliği sonunda seken bir interpolatör.
CycleInterpolator Animasyonu belirli sayıda döngü için tekrarlayan bir interpolasyon.
DecelerateInterpolator Değişim hızı hızlı başlayıp yavaşlayan bir interpolatör.
LinearInterpolator Değişim hızı sabit olan bir interpolasyon aracı.
OvershootInterpolator Değişikliği ileriye doğru fırlayan ve son değeri aşan, ardından geri gelen bir interpolasyon işlevi.
TimeInterpolator Kendi interpolatörünüzü uygulamanıza olanak tanıyan bir arayüz.

ValueAnimator kullanarak animasyon oluşturma

ValueAnimator sınıfı, animasyon süresince belirli bir türdeki değerlere animasyon eklemenize olanak tanır. Bunun için, animasyon boyunca kullanılacak bir dizi int, float veya renk değeri belirtmeniz gerekir. ValueAnimator, ofInt(), ofFloat() veya ofObject() fabrika yöntemlerinden birini çağırarak ValueAnimator elde edersiniz. Örneğin:

Kotlin

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

Java

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

Bu kodda, ValueAnimator, start() yöntemi çalıştırıldığında 1.000 ms boyunca animasyonun 0 ile 100 arasındaki değerlerini hesaplamaya başlar.

Aşağıdaki adımları uygulayarak animasyon uygulanacak ö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 yöntemi çalıştırıldığında start(), 1.000 ms boyunca MyTypeEvaluator tarafından sağlanan mantığı kullanarak startPropertyValue ile endPropertyValue arasındaki animasyon değerlerini hesaplamaya başlar.

Aşağıdaki kodda gösterildiği gibi, ValueAnimator nesnesine AnimatorUpdateListener ekleyerek animasyonun 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 bunu görünümlerinizden birinin özelliğinde kullanabilirsiniz. Dinleyiciler hakkında daha fazla bilgi için Animasyon dinleyicileri bölümüne bakın.

ObjectAnimator kullanarak animasyon oluşturma

ObjectAnimator, ValueAnimator öğesinin bir alt sınıfıdır (önceki bölümde ele alınmıştır) ve ValueAnimator öğesinin zamanlama motoru ile değer hesaplamasını, hedef nesnenin adlandırılmış bir özelliğini canlandırma özelliğiyle birleştirir. Bu sayede, animasyonlu özellik otomatik olarak güncellendiğinden artık ValueAnimator.AnimatorUpdateListener uygulamanız gerekmediği için herhangi bir nesnenin animasyonunu yapmak çok daha kolaydır.

ObjectAnimator öğesini oluşturmak ValueAnimator öğesini oluşturmaya benzer. Ancak, animasyon uygulanacak değerlerin yanı sıra nesneyi ve bu nesnenin özelliğinin adını (String 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 güncelleme özelliklerinin doğru şekilde çalışması için aşağıdakileri yapmanız gerekir:

  • Animasyon uyguladığınız nesne özelliğinin, set<PropertyName>() biçiminde bir ayarlayıcı işlevi (camel case) olmalıdır. ObjectAnimator, animasyon sırasında mülkü otomatik olarak güncellediğinden bu belirleyici yöntemiyle mülke erişebilmesi gerekir. Örneğin, özellik adı foo ise setFoo() yöntemine sahip olmanız gerekir. Bu ayarlayıcı yöntem yoksa üç seçeneğiniz vardır:
    • Gerekli haklara sahipseniz sınıfına ayarlayıcı yöntemini ekleyin.
    • Değiştirme hakkınız olan bir sarmalayıcı sınıfı kullanın ve bu sarmalayıcının değeri geçerli bir ayarlayıcı yöntemiyle alıp orijinal nesneye iletmesini sağlayın.
    • Bunun yerine ValueAnimator kullanın.
  • ObjectAnimator fabrika yöntemlerinden birinde values... parametresi için yalnızca bir değer belirtirseniz bu değerin animasyonun bitiş değeri olduğu varsayılır. Bu nedenle, animasyon uyguladığınız nesne özelliğinin, animasyonun başlangıç değerini elde etmek için kullanılan bir getter işlevi olmalıdır. Getter işlevi get<PropertyName>() biçiminde olmalıdır. Örneğin, özellik adı foo ise getFoo() yöntemine sahip olmanız gerekir.
  • Animasyon uyguladığınız özelliğin alıcı (gerekirse) ve belirleyici yöntemleri, ObjectAnimator için belirttiğiniz başlangıç ve bitiş değerleriyle aynı türde çalışmalıdır. Örneğin, aşağıdaki ObjectAnimator öğesini oluşturuyorsanız targetObject.setPropName(float) ve targetObject.getPropName() öğelerine sahip olmanız gerekir:
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • Hangi mülkü veya nesneyi canlandırdığınıza bağlı olarak, ekranın güncellenmiş animasyonlu değerlerle kendini yeniden çizmesini zorlamak için bir Görünümde invalidate() yöntemini çağırmanız gerekebilir. Bu işlemi onAnimationUpdate() geri çağırmasında yaparsınız. Örneğin, bir Drawable nesnesinin renk özelliğini canlandırmak, yalnızca bu nesne kendini yeniden çizdiğinde ekranda güncellemeler yapılmasına neden olur. Görünümdeki tüm mülk ayarlayıcılar (ör. setAlpha() ve setTranslationX()) Görünüm'ü düzgün ş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. Dinleyiciler hakkında daha fazla bilgi için Animasyon dinleyicileri bölümüne bakın.

AnimatorSet kullanarak birden fazla animasyonu koreografiye etme

Ç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ı AnimatorSet içinde birlikte 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ı belirleyebilirsiniz. Ayrıca, AnimatorSet nesneleri iç içe yerleştirebilirsiniz.

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

  1. bounceAnim oynatılıyor.
  2. Aynı anda squashAnim1, squashAnim2, stretchAnim1 ve stretchAnim2 oynatır.
  3. bounceBackAnim oynatılıyor.
  4. fadeAnim oynatılı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 işleyicileri

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

  • Animator.AnimatorListener
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() - Animasyonun her karesinde çağrılır. Bu etkinliği dinleyerek ValueAnimator tarafından animasyon sırasında oluşturulan hesaplanmış değerleri kullanabilirsiniz. Değeri kullanmak için ValueAnimator yöntemini kullanarak geçerli animasyonlu değeri almak üzere etkinliğe iletilen ValueAnimator nesnesini sorgulayın.getAnimatedValue() ValueAnimator kullanıyorsanız bu dinleyiciyi uygulamanız gerekir.

      Hangi mülkü veya nesneyi canlandırdığınıza bağlı olarak, ekranın söz konusu alanının yeni animasyonlu değerlerle yeniden çizilmesini zorlamak için bir Görünümde invalidate() çağırmanız gerekebilir. Örneğin, bir Drawable nesnenin renk özelliğini canlandırmak, yalnızca nesne kendini yeniden çizdiğinde ekranda güncellemeler yapılmasına neden olur. Görünümdeki tüm mülk ayarlayıcılar (ör. setAlpha() ve setTranslationX()), Görünüm'ü düzgün ş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.

AnimatorListenerAdapter sınıfını genişletebilirsiniz. Animator.AnimatorListener arayüzünün tüm yöntemlerini uygulamak istemiyorsanız Animator.AnimatorListener arayüzünü uygulamayın. 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 yalnızca onAnimationEnd() geri çağırma işlevi için bir AnimatorListenerAdapter oluşturur:

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 nesnelerindeki düzen değişikliklerine animasyon ekleme

Özellik animasyonu sistemi, ViewGroup nesnelerindeki değişikliklere animasyon ekleme ve View nesnelerine kolayca animasyon ekleme olanağı sunar.

LayoutTransition sınıfıyla bir ViewGroup içindeki düzen değişikliklerine animasyon ekleyebilirsiniz. Bir ViewGroup içindeki görünümler, ViewGroup'a eklendiğinde veya ViewGroup'tan kaldırıldığında ya da bir View'ın setVisibility() yöntemi VISIBLE, INVISIBLE veya GONE ile çağrıldığında görünme ve kaybolma animasyonundan geçebilir. ViewGroup'daki kalan Görünümler de Görünüm eklediğinizde veya kaldırdığınızda yeni konumlarına animasyonla geçebilir. LayoutTransition nesnesinde aşağıdaki animasyonları setAnimator() işlevini çağırarak ve aşağıdaki LayoutTransition sabitlerinden birini içeren bir Animator nesnesi ileterek tanımlayabilirsiniz:

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

Düzen geçişlerinizin görünümünü özelleştirmek için bu dört etkinlik türü için kendi özel animasyonlarınızı tanımlayabilir veya animasyon sistemine yalnızca 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 doğru olarak ayarlamak, ViewGroup'a eklenen veya ViewGroup'tan kaldırılan View'ları ve ViewGroup'daki kalan View'ları otomatik olarak animasyonlandırır.

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 animasyonlar tanımlamanıza olanak tanır. Bu nesne, bir Animator nesnesi için sarmalayıcı görevi görür ve belirtilen görünüm durumu ("basıldı" veya "odaklandı" gibi) her değiştiğinde bu animasyonu çağırır.

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

Örneğin, aşağıdaki dosya, görünüme 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>

Durum listesi animatörünü bir görünüme eklemek için android:stateListAnimator özelliğini aşağıdaki gibi ekleyin:

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

Artık bu düğmenin durumu değiştiğinde animate_scale.xml içinde tanımlanan animasyonlar kullanılır.

Alternatif olarak, 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.

Alternatif olarak, görünümün özelliklerini canlandırmak yerine AnimatedStateListDrawable kullanarak durum değişiklikleri arasında çizilebilir bir animasyon oynatabilirsiniz. Android 5.0'daki bazı sistem widget'ları 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 sistemi tarafından bilinmeyen bir türü canlandırmak 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ğerlendiriciler tarafından desteklenir.

TypeEvaluator arayüzünde yalnızca bir uygulama yöntemi vardır: evaluate() yöntemi. Bu sayede, kullandığınız animatörün animasyonun mevcut noktasında animasyonlu özelliğiniz için uygun bir değer döndürmesine olanak tanırsınız. FloatEvaluator sınıfında bu işlemin 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) çalıştığında animasyonun geçerli geçen kısmını (0 ile 1 arasında bir değer) hesaplar ve ardından kullandığınız interpolatöre bağlı olarak bunun enterpolasyonlu bir sürümünü hesaplar. Ara değer kesri, TypeEvaluator öğenizin fraction parametresi aracılığıyla aldığı değerdir. Bu nedenle, animasyonlu değerleri hesaplarken ara değer belirleyiciyi dikkate almanız gerekmez.

İnterpolasyonları kullanma

Bir interpolatör, animasyondaki belirli değerlerin zamanın bir fonksiyonu olarak nasıl hesaplandığını tanımlar. Örneğin, animasyonların animasyonun tamamında doğrusal olarak gerçekleşmesini belirtebilirsiniz. Bu durumda animasyon, tüm süre boyunca eşit şekilde hareket eder. Ayrıca, 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 interpolasyonlar, animasyonun geçen süresini temsil eden bir kesir alır. İnterpolasyonlar, bu kesri sağlamayı amaçladığı animasyon türüyle eşleşecek şekilde değiştirir. Android sistemi, android.view.animation package içinde bir dizi ortak interpolasyon aracı sağlar. Bunların hiçbiri ihtiyaçlarınıza uymuyorsa TimeInterpolator arayüzünü uygulayabilir ve kendi arayüzünüzü oluşturabilirsiniz.

Örneğin, varsayılan interpolasyon işlevinin AccelerateDecelerateInterpolator ve LinearInterpolator işlevinin, interpolasyonlu kesirleri nasıl hesapladığı aşağıda karşılaştırılmıştır. LinearInterpolator, geçen süre kesri üzerinde etkili değildir. AccelerateDecelerateInterpolator, animasyona doğru hızlanır ve animasyondan uzaklaşırken 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;
}

LinearInterpolator

Kotlin

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

Java

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

Aşağıdaki tabloda, 1.000 ms süren bir animasyon için bu interpolasyon işlevleri tarafından hesaplanan yaklaşık değerler gösterilmektedir:

ms elapsed Geçen kesir/İnterpolasyonlu kesir (Doğrusal) İnterpolasyonlu kesir (Hızlanma/Yavaşlama)
0 0 0
200 .2 0,1
400 0,4 0,345
600 0,6 .654
800 0,8 0,9
1000 1 1

Tabloda gösterildiği gibi, LinearInterpolator değerleri aynı hızda değiştirir. Her 200 ms'de 0,2 değerinde değişiklik yapılır. AccelerateDecelerateInterpolator, 200 ms ile 600 ms arasında değerleri LinearInterpolator'dan daha hızlı, 600 ms ile 1.000 ms arasında ise daha yavaş değiştirir.

Animasyon karelerini belirtme

Bir Keyframe nesnesi, animasyonun belirli bir zamanında belirli bir durumu tanımlamanıza olanak tanıyan bir zaman/değer çiftinden oluşur. Her animasyon karesinin, önceki animasyon karesinin zamanı ile bu animasyon karesinin zamanı arasındaki aralıkta animasyonun davranışını kontrol etmek için kendi interpolatörü de olabilir.

Keyframe nesnesi oluşturmak için uygun Keyframe türünü elde etmek üzere fabrika yöntemlerinden birini (ofInt(), ofFloat() veya ofObject()) kullanmanız gerekir. Ardından, PropertyValuesHolder nesnesi elde etmek için ofKeyframe() fabrika yöntemini çağırırsınız. Nesneyi aldıktan sonra PropertyValuesHolder nesnesini ve animasyon eklenecek nesneyi ileterek bir animatör elde edebilirsiniz. Aşağıdaki kod snippet'inde bu işlemin 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ünümlere animasyon ekleme

Özellik animasyonu sistemi, View nesnelerinin kolayca animasyonunu yapmanıza olanak tanır ve görünüm animasyonu sistemine göre birkaç avantaj sunar. Görünüm animasyon sistemi, Görünüm nesnelerini çizilme şekillerini değiştirerek dönüştürdü. Bu işlem, Görünüm'ün kendisinde değiştirilecek özellikler olmadığından her Görünümün kapsayıcısında gerçekleştirildi. Bu işlem, View'un animasyonlu olmasına neden oldu ancak View nesnesinde herhangi bir değişikliğe yol açmadı. Bu durum, ekranda farklı bir konuma çizilmiş olsa bile bir nesnenin orijinal konumunda var olmaya devam etmesi gibi davranışlara yol açtı. Android 3.0'da bu dezavantajı ortadan kaldırmak için yeni özellikler ve ilgili getter ve setter yöntemleri eklendi.

Özellik animasyonu sistemi, Görünüm nesnelerindeki gerçek özellikleri değiştirerek ekrandaki Görünümlere animasyon ekleyebilir. Ayrıca, Görünümler, özellikleri her değiştirildiğinde ekranı yenilemek için invalidate() yöntemini de otomatik olarak çağırır. View sınıfındaki, özellik animasyonlarını kolaylaştıran yeni özellikler şunlardır:

  • translationX ve translationY: Bu özellikler, görünümün düzen kapsayıcısı tarafından belirlenen sol ve üst koordinatlarından ne kadar uzaklıkta olduğunu kontrol eder.
  • rotation, rotationX ve rotationY: Bu özellikler, 2D'de (rotation özelliği) ve 3D'de pivot noktası etrafındaki döndürmeyi kontrol eder.
  • scaleX ve scaleY: Bu özellikler, bir görünümün pivot noktası etrafındaki 2D ölçeklendirmesini kontrol eder.
  • pivotX ve pivotY: Bu özellikler, döndürme ve ölçeklendirme dönüşümlerinin gerçekleştiği pivot noktasının konumunu kontrol eder. Varsayılan olarak, pivot noktası nesnenin ortasında bulunur.
  • x ve y: Bunlar, Görünüm'ün kapsayıcısındaki son konumunu sol ve üst değerler ile translationX ve translationY değerlerinin toplamı olarak tanımlayan basit yardımcı özelliklerdir.
  • alpha: Görünümdeki alfa şeffaflığını gösterir. Bu değer varsayılan olarak 1'dir (opak). 0 değeri ise tam şeffaflığı (görünür değil) ifade eder.

Bir View nesnesinin rengi veya dönüş değeri gibi bir özelliğini canlandırmak için yapmanız gereken tek şey bir özellik animatörü oluşturmak ve canlandırmak istediğiniz View özelliğini belirtmektir. Örneğin:

Kotlin

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

Java

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

Animatör 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, tek bir temel Animator nesnesi kullanarak bir View öğesinin çeşitli özelliklerini paralel olarak canlandırmanın basit bir yolunu sunar. Görünüm özelliklerinin gerçek değerlerini değiştirdiği için ObjectAnimator gibi davranır ancak birçok özelliğe aynı anda animasyon uygularken daha verimlidir. Ayrıca ViewPropertyAnimator kullanma kodu çok daha kısa ve okunması kolaydır. Aşağıdaki kod snippet'leri, bir görünümün x ve y özelliklerine aynı anda animasyon uygularken birden fazla ObjectAnimator nesnesi, tek bir ObjectAnimator ve ViewPropertyAnimator kullanma arasındaki farkları gösterir.

Birden çok ObjectAnimator nesnesi

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();

Bir 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 Geliştiricileri blog yayınını inceleyin.

Animasyonları XML'de bildirme

Özellik animasyonu sistemi, programatik olarak yapmak yerine XML ile özellik animasyonları bildirmenize 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 özellik animasyonu API'lerini kullanan animasyon dosyalarını eski görünüm animasyonu çerçevesini kullananlardan ayırt etmek için Android 3.1'den itibaren özellik animasyonlarının XML dosyalarını res/animator/ dizinine kaydetmeniz gerekir.

Aşağıdaki özellik animasyonu sınıfları, aşağıdaki XML etiketleriyle XML bildirimi desteğine sahiptir:

XML bildiriminizde kullanabileceğiniz özellikleri bulmak için Animasyon kaynakları bölümüne bakın. Aşağıdaki örnekte, iki grup nesne animasyonu sırayla oynatılır. İlk iç içe yerleştirilmiş grupta iki nesne animasyonu birlikte oynatılı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 genişletmeniz ve ardından animasyon kümesini başlatmadan önce tüm animasyonların hedef nesnelerini ayarlamanız gerekir. setTarget() işlevini çağırmak, kolaylık sağlamak amacıyla AnimatorSet öğesinin tüm alt öğeleri için tek bir hedef nesne ayarlar. Aşağıdaki kodda bu işlemin 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();

Ayrıca, aşağıdaki örnekte gösterildiği gibi XML'de ValueAnimator bildirebilirsiniz:

<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 değerini kullanmak için nesneyi genişletmeniz, AnimatorUpdateListener eklemeniz, güncellenen animasyon değerini almanız ve bunu görünümlerinizden birinin özelliğinde kullanmanız gerekir. Bu işlem aşağıdaki kodda gösterilmiştir:

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();

Mülk animasyonlarını tanımlamaya yönelik XML söz dizimi hakkında bilgi için Animasyon kaynakları başlıklı makaleye bakın.

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

Kullanıcı arayüzünü güncelleyen animatörler, animasyonun çalıştığı her kare için ek oluşturma çalışmasına neden olur. Bu nedenle, kaynak yoğun animasyonlar kullanmak uygulamanızın performansını olumsuz etkileyebilir.

Kullanıcı arayüzünüzü canlandırmak için gereken çalışma, oluşturma işlem hattının animasyon aşamasına eklenir. Profil GPU oluşturma'yı 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 kılavuzu'na bakın.