Soru & Cevap

Android | Animasyon "Her" Cihazda Çalışmıyor

10.06.2017 - 10:41

Merhabalar. Android Studio üzerinden bir uygulama geliştirmekteyim. Veri alışverişi ile alakalı olduğu için roket-Dünya-uzay üçlüsüyle oyun görünümlü bir dizayn konseptini sağladım. Fakat yaptığım animasyonun her cihazda çalışmadığını fark ettim. 4 farklı emülatörde problemsiz, 4 gerçek cihazdanın da 2 sinde problem çıktı. Animasyon başlamadan bitiyor. Alternatifler oluşturdum fakat yavaş çalışıyor ve hoş gözükmüyor. Olay şöyle; arkaplanda bir scrollview var, (custom). Bu scroll en aşağıda başlıyor ve yukarıya doğru çıkıyor. Bu sırada roket de dünyanın tam üzerinde duruyor. Roketi fırlatmak için

1) Value Animator ile setY yaptırıyorum, olmuyor (çalışmayan cihazlarda, yoksa diğerleri problemsiz).
2) Translate Animation ile direkt hedefe gönderiyorum, olmuyor.
3) Timer ile her milisaniyede setY yaptırıyorum. Oluyor fakat durgun ve kasma belirtileri gösteriyor. 

ValueAnimator un olması tercih çünkü 
setInterpolator(new FastOutSlowInInterpolator()); ile aniden kalkıp yavaşça bitmesini sağlıyorum. Kodlar şunlar;
 

void RoketiFirlat(int tur)
    {
        final float RoketY = Roket.getY();
        final float RoketYSon = DunyaUstu.getBottom() - DunyaUstu.getBottom() / 2;
        Log.d("slide", "Roket Y Son=" + RoketYSon);
        if (tur == 1)
        {
            Animation roketGonder = new TranslateAnimation(0, 0, RoketY, RoketYSon);
            Log.d("slide", RoketY + "\n" + RoketYSon);
            roketGonder.setZAdjustment(Animation.ZORDER_TOP);
            roketGonder.setDuration(5000);
            Roket.startAnimation(roketGonder);
        }
        if (tur == 2)
        {
            Roket.post(new Runnable()
            {
                @Override
                public void run()
                {
                    Log.d("slide", "Roket Y=" + RoketY + "\n Baslik Top=" + RoketYSon);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
                    {
                        ValueAnimator hareketEtRoket = ValueAnimator.ofFloat(RoketY, RoketYSon);
                        hareketEtRoket.setDuration(5000);
                        hareketEtRoket.setInterpolator(new FastOutSlowInInterpolator());
                        hareketEtRoket.addListener(new Animator.AnimatorListener()
                        {
                            @Override
                            public void onAnimationStart(Animator animation)
                            {
                                Arkaplan.setEnableScrolling(false);
                            }

                            @Override
                            public void onAnimationEnd(Animator animation)
                            {
                                Arkaplan.setEnableScrolling(false);
                            }

                            @Override
                            public void onAnimationCancel(Animator animation)
                            {

                            }

                            @Override
                            public void onAnimationRepeat(Animator animation)
                            {

                            }
                        });
                        hareketEtRoket.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
                        {
                            @Override
                            public void onAnimationUpdate(ValueAnimator animation)
                            {
                                float nere = (float) animation.getAnimatedValue();
                                Roket.setY(nere);
                            }
                        });
                        hareketEtRoket.start();
                    }
                    else
                    {
                        Log.d("slide", "Animasyon Otomatik Olarak Bitti");
                        Roket.setY(RoketYSon);
                    }
                }
            });
        }
        if (tur == 3)
        {
            final Timer scrollRoket = new Timer();
            roketSuan = (int) Roket.getY();
            scrollRoket.scheduleAtFixedRate(new TimerTask()
            {
                @Override
                public void run()
                {
                    Roket.setY(roketSuan);
                    roketSuan--;
                    if (Roket.getY() <= RoketYSon)
                    {
                        scrollRoket.cancel();
                    }
                }
            }, 0, 1);
        }
    }

Handlerlar, UI Thread, Z adjustment gibi farklı çözümler denedim fakat bir türlü olmadı. Ayriyeten 11 API üstü bütün cihazlar, yani son else ten dolayı değil zira oraya koyduğum bir Log u görmüyor. Kaldı ki "aniamsyon bitince" kısmını görüp çalıştırıyor. Sadece görüntü yok yani. Aynısı Arkaplan tanımlı ScrollView için de geçerli Onda da Value Animator ve Timer kullanıyorum. Yine sadece Timer çalışıyor. Gözümden kaçırdığım bir şey mi var acaba? Cevaplarınızı bekliyorum, şimdiden teşekkürler

11 Görüntülenme

1 Cevap

Sitedeki sorulara cevap verebilmek için giriş yapın ya da üye olun.

Profile picture for user gmyucalfarukeren
gmyucalfarukeren
22.02.2023 - 01:28

Merhaba Eşref. Animasyonunuzun her cihazda çalışmadığını belirtmişsiniz ve bu nedenle alternatif çözümler denemişsiniz. Ancak yavaş çalışıyorlar ve hoş görünmüyorlar. ValueAnimator'un çalışması tercih edildiği için, animasyonun başında aniden kalkıp yavaşça bitmesini sağlamak için setInterpolator (new FastOutSlowInInterpolator ()) yöntemini kullanıyorsunuz. Kodlarınıza göre, bir ScrollView arkaplanda var ve scroll en aşağıda başlıyor ve yukarı doğru hareket ediyor. Roketi fırlatmak için bir Value Animator kullanıyorsunuz, ancak bazı cihazlarda animasyon başlamadan bitiyor. TranslateAnimation ve Timer da denemişsiniz

Sorununuzun çözümüne dair bazı önerilerim şunlar

  1. Animasyonun hedeflenen cihazlarda çalışması için optimize edilmiş olmadığını belirleyin. Örneğin, performans sorunları yaşadığınız cihazların özelliklerine bakın ve animasyonunuzun bunlara uygun şekilde optimize edildiğinden emin olun

  2. Roketi hareket ettirmeden önce, arkaplandaki ScrollView'un tam olarak durduğundan emin olun. Bazı cihazlarda animasyon başlamadan önce ScrollView hedef konumuna ulaşmayabilir. Bu durumda animasyon da çalışmayacaktır

  3. ValueAnimator'un çalışmasını sağlamak için setInterpolator () yöntemini kullanıyorsunuz. Ancak, bu yöntem her cihazda aynı sonucu vermez. Belki de FastOutSlowInInterpolator () yöntemini kullanmak yerine, her cihaz için özelleştirilmiş bir Interpolator kullanarak animasyonunuzu optimize edebilirsiniz

  4. TranslateAnimation kullanırken, animasyonun doğru şekilde çalışması için Roket'in başlangıç ​​pozisyonunun doğru olduğundan emin olun. TranslateAnimation, x ve y koordinatlarında mutlak değerler kullanır. Roket'in doğru konumda başlamadığı durumlarda, animasyon çalışmayacaktır

  5. Timer kullanırken animasyonunuzu daha akıcı hale getirmek için, Timer'ın içindeki işlemi arkaplanda bir Thread'de yapmayı deneyin. Bu, animasyonunuzu daha akıcı hale getirebilir ve durgunluk sorunlarını önleyebilir

  6. Animasyonu gerçekleştirmeden önce, cihazın performansına etki edebilecek diğer uygulamaların veya işlemlerin olmadığından emin olun. Animasyonunuzu test ederken, herhangi bir arka planda çalışan uygulamayı kapatarak veya donanım özelliklerini artırmak için cihazınızı yeniden başlatarak performansı artırabilirsiniz