Animacja Androida się nie powtarza

85

Próbuję zrobić prostą animację, która będzie się powtarzać kilka razy (lub w nieskończoność).
Wygląda na to, że android:repeatCountnie działa!
Oto mój zasób animacji z /res/anim/first_animation.xml:

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false"
    android:repeatCount="infinite"
    >
    <scale
        android:interpolator="@android:anim/decelerate_interpolator"
        android:duration="500"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="1.2"
        android:toYScale="1.2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillAfter="false" />
    <scale
        android:interpolator="@android:anim/accelerate_interpolator"
        android:startOffset="500"
        android:duration="500"
        android:fromXScale="1.2"
        android:fromYScale="1.2"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillAfter="false" />
</set>

Najpierw powinien przeskalować obraz od rozmiaru 1,0 do 1,2 w 500 ms.
A następnie skaluj go z powrotem do 1,0 w 500 ms.
Oto jak go używam:

Animation firstAnimation = AnimationUtils.loadAnimation(this, R.anim.first_animation);
imgView.startAnimation(firstAnimation);

Wykonuje jeden cykl, a następnie się kończy.
Skala w górę, potem w dół, a następnie zatrzymuje się.

Jak mogę to zrobić zgodnie z przeznaczeniem?

Pavel Chernov
źródło
Czym jest imgView w twoim kodzie java?
clifgray

Odpowiedzi:

63

Aktualizacja: We wrześniu 2011 r. Inżynier Android rozwiązał ten problem w większości. Atrybuty, które zostały zignorowane w XML teraz działają, z wyjątkiem repeatCounti fillEnabledktóre są nadal ignorowane (celowo z jakiegoś powodu). Oznacza to, że niestety nadal nie jest łatwo powtórzyć AnimationSet.

Aby uzyskać szczegółowe informacje, zapoznaj się z omówieniem w zaktualizowanych dokumentach (wyjaśnia, które atrybuty są ignorowane, które działają, a które są przekazywane dzieciom). Aby dowiedzieć się więcej o tym fillAfter, co fillBeforei fillEnabledfaktycznie robią, przeczytaj wpis na blogu inżyniera (Chet Haase) o tym tutaj .


Oryginalna odpowiedź

Aby rozwinąć odpowiedzi Pawła i innych: to prawda, że <set>tag jest śmiesznie błędny. Nie radzi sobie poprawnie z repeatCountwieloma innymi atrybutami.

Spędziłem kilka godzin, zastanawiając się, z czym może, a czego nie może sobie poradzić, i przesłałem zgłoszenie błędu / problem tutaj: numer 17662

Podsumowując (dotyczy to AnimationSets):

setRepeatCount () / android: repeatCount

Ten atrybut (podobnie jak repeatMode) nie działa w kodzie ani w XML. Utrudnia to powtarzanie całego zestawu animacji.

setDuration () / android: duration

Ustawienie tego w zestawie animacji w kodzie DZIAŁA (zastępuje wszystkie czasy trwania animacji podrzędnych), ale nie w przypadku uwzględnienia w tagu w XML

setFillAfter () / android: fillAfter

Działa to zarówno w kodzie, jak i XML dla tagu. O dziwo, udało mi się to również działać bez konieczności ustawiania fillEnabled na true.

setFillBefore () / android: fillBefore

Wydaje się, że nie ma żadnego wpływu / jest ignorowane zarówno w kodzie, jak i XML

setFillEnabled () / android: fillEnabled

Wydaje się, że nie ma żadnego wpływu / jest ignorowane zarówno w kodzie, jak i XML. Nadal mogę uzyskać fillAfter do pracy, nawet bez włączania fillEnabled lub ustawiania fillEnabled na false.

setStartOffset () / android: startOffset

Działa to tylko w kodzie, a nie w XML.

Tony Chan
źródło
48

Zauważyłem, że tag <set> ma wadliwą implementację w klasie AnimationSet .
Nie radzi sobie poprawnie z repeCount .
Co możemy zrobić - to ustawić repeatCount bezpośrednio w tagu <scale> .

Ten zasób XML działa dobrze:

<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:duration="200"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="1.05"
    android:toYScale="1.05"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatMode="reverse"
    android:fillAfter="false"
    android:repeatCount="24"
/>

Niestety jest to ograniczone do tylko jednej animacji naraz.
Nie możemy w ten sposób zdefiniować sekwencji animacji ...

Pavel Chernov
źródło
W zestawie uruchamiam 2 animacje i nie sprawiają mi one żadnego problemu. uprzejmie powiedz mi o którym problemie mówisz? który błąd? obecnie pracuję na 1.6 sdk
AZ_
Deklarowanie repeatCount w xml działa, ale nie w kodzie
onmyway133
39

Powinieneś dołączyć atrybut

android:repeatCount="infinite"

Ale w animacji „skali” nie ma „zestawu”

Macumbaomuerte
źródło
1
ale czy te animacje będą czekać na zakończenie poprzedniej? dzięki
filthy_wizard
Dzięki, zadziałało! Ustawienie go programowo nie było z jakiegoś powodu.
fala wiśni,
Dzięki! To zadziałało. Ale to jest ciągłe. Czy można to zrobić, powiedz co 5 sekund?
d34th4ck3r
32

Aby uzyskać powtarzającą się animację, użyłem słuchacza animacji i ponownie wywołałem animację po jej zakończeniu. To sprawia, że ​​siatka aparatu skupia się jak animacja z nawiasami.

Oto XML układu animacji

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
    android:fromXScale="1.0"
    android:toXScale=".7"
    android:fromYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toYScale=".7"
    android:duration="1000"/>
<scale 
    android:duration="1000"
    android:fromXScale=".7"
    android:toXScale="1.0"
    android:fromYScale=".7"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toYScale="1.0"
    android:startOffset="1000"/>

</set>

Oto kod java

 public void startAnimation() {

            View brackets = findViewById(R.id.brackets);
            brackets.setVisibility(View.VISIBLE);

            Animation anim = AnimationUtils.loadAnimation(BuzzFinderActivity.this, R.anim.crosshair_focusing);
            anim.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationEnd(Animation arg0) {
                    Animation anim = AnimationUtils.loadAnimation(BuzzFinderActivity.this, R.anim.crosshair_focusing);
                    anim.setAnimationListener(this);
                    brackets.startAnimation(anim);

                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onAnimationStart(Animation arg0) {
                    // TODO Auto-generated method stub

                }

            });


            brackets.startAnimation(anim);
}
Danuofr
źródło
2
Tak, to powinna być poprawna odpowiedź. Działa na wszystkich urządzeniach i na poziomie systemu operacyjnego
Smeet
pomogło mi też, ale usunąłem te dwie linie z metody End Animation anim = AnimationUtils.loadAnimation (BuzzFinderActivity.this, R.anim.crosshair_focusing); anim.setAnimationListener (this);
aida,
10

Miałem również ten sam problem ... w pliku XMl umieściłem androida: repeatCount = "infinite" ... teraz działa dobrze ...

  <translate 
           android:fromXDelta="0"
           android:toXDelta="80"
           android:duration="1000"
           android:repeatCount="infinite"   
           android:repeatMode="reverse" 
           android:pivotX="50%"
           android:pivotY="50%"                             
           android:fillAfter="true"/>

abhilash
źródło
9

możesz wypróbować ten kod. W swoim kodzie po prostu dodaj,

firstAnimation.setRepeatCount(5);

Spowoduje to powtórzenie animacji przez określony czas

firstAnimation.setRepeatCount(Animation.INFINITE);
firstAnimation.setRepeatMode(Animation.INFINITE);

Animacja będzie powtarzana w nieskończoność.

Informatyka
źródło
4
repeatModepowinno być albo RESTARTalboREVERSE
xinthink
to jest dokładnie to, czego chcę, ustawione dynamicznie na nieskończoność.
Varun Chaudhary
2
setRepeat nie działa zgodnie z code.google.com/p/android/issues/detail?id=17662
ElliotM
4

Próbowałem użyć kodu Daniela, aby pokazać animację dokładną liczbę razy i miałem problem: animacja została wyświetlona mniej więcej n / 2 razy, gdy oczekiwano n razy.

Więc zmodyfikowałem kod Daniela:

//...
@Override
public void onAnimationEnd(Animation arg0) {
    mCurrentCount++;
    if (mCurrentCount < REPEAT_COUNT) {  
        Animation anim = AnimationUtils.loadAnimation(BuzzFinderActivity.this, R.anim.crosshair_focusing);
        anim.setAnimationListener(this);
        brackets.post(new Runnable() {
            @Override
            public void run() {
                brackets.startAnimation(anim);
            }
        }  
    } 
}
//... 

Korzystając z wariantu pokazanego powyżej, animacja jest pokazana dokładnie REPEAT_COUNT razy, ponieważ metoda View.post () daje możliwość uruchomienia nowej animacji po zakończeniu wszystkich akcji związanych z poprzednią animacją.

Denis
źródło
3

musisz dodać tylko jedną linię w kodzie XML, który zasugerowałem poniżej.

<scale
    android:duration="500"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="1.2"
    android:toYScale="1.2"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite" // just add this one line 
    android:fillAfter="false"
    />
</set>
Mitesh Sawant
źródło
3

Rozwiązałem ten problem, używając android:repeatMode="reverse"wcześniej w moim projekcie.

<scale
    android:interpolator="@android:anim/decelerate_interpolator"
    android:duration="500"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="1.2"
    android:toYScale="1.2"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatMode="reverse"
    android:repeatCount="infinite" />
Huseyin
źródło
2

Z systemem Android SDK w wersji 4.0.3:

W podanych elementach animacji:

android: repeatCount = "- 1"

sprawia, że ​​jest to nieskończona animacja.

Kurt Junghanns
źródło
Dzięki! Działa dobrze na 4.2 bez żadnego obejścia
ruX
2

Dodaj następującą klasę do swojego projektu:

import android.view.View;
import android.view.animation.Animation;

public class AnimationRepeater implements Animation.AnimationListener
{
    private View view;
    private Animation animation;
    private int count;

    public AnimationRepeater(View view, Animation animation)
    {
        this.view = view;
        this.animation = animation;
        this.count = -1;
    }

    public AnimationRepeater(View view, Animation animation, int count)
    {
        this.view = view;
        this.animation = animation;
        this.count = count;
    }

    public void start()
    {
        this.view.startAnimation(this.animation);
        this.animation.setAnimationListener(this);
    }

    @Override
    public void onAnimationStart(Animation animation) { }

    @Override
    public void onAnimationEnd(Animation animation)
    {
        if (this.count == -1)
            this.view.startAnimation(animation);
        else
        {
            if (count - 1 >= 0)
            {
                this.animation.start();
                count --;
            }
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) { }
}

Aby uzyskać nieskończoną pętlę widoku, wykonaj następujące czynności:

Animation a = AnimationUtils(Context, R.anim.animation);
new AnimationRepeater(View, a).start();

Jeśli chcesz powtórzyć animację tylko N razy, wykonaj następujące czynności:

Animation a = AnimationUtils(Context, R.anim.animation);
new AnimationRepeater(View, a, int N).start();

N oznacza liczbę powtórzeń.

domi
źródło
1

Większość moich rzeczy robię programowo i mogę się spóźnić lub nieefektywnie na tym, ale to, ale osiągnąłem cel powtórzenia zestawu animacji (mam nawet 2 naprzemienne zestawy animacji). Wszystko, co robi ten kod, to po prostu zanikanie na jednym obrazie, pauza, a następnie zanikanie, zanikanie na innym obrazie, pauza, zanikanie i przywracanie pierwszego obrazu (przepłucz i powtórz). Najpierw zdefiniowałem moje widoki obrazu:

    final ImageView purple = (ImageView)findViewById(R.id.purp);
    final ImageView yellow = (ImageView)findViewById(R.id.yell);
    purple.setVisibility(View.INVISIBLE);
    yellow.setVisibility(View.INVISIBLE);

Następnie stworzyłem dwa liczniki czasu, liczniki czasu zadań i programy obsługi, aby radzić sobie, kiedy rozpocząć i zatrzymać każdą animację:

    Timer p = new Timer();
    TimerTask pu = new TimerTask() {
        public void run() {
                handler1.post(new Runnable() {
                        public void run() 
                        {
                           fadein(purple);
                        }
               });
        }};
        p.schedule(pu, 6000, 12000);

    final Handler handler2 = new Handler();

    Timer y = new Timer();
    TimerTask ye = new TimerTask() {
        public void run() {
                handler2.post(new Runnable() {
                        public void run() 
                        {
                           fadein(yellow);
                        }
               });
        }};

        y.schedule(ye, 0, 12000);

Wreszcie, zamiast tworzyć zestawy animacji przez dodawanie animacji, po prostu słuchacze animacji określają, kiedy rozpocząć każdą animację:

public void fadein (final ImageView image)
{
    Animation anim = new AlphaAnimation(0, 1);

    anim.setDuration(2000);

    image.startAnimation(anim);
    anim.setAnimationListener(new AnimationListener() {
        public void onAnimationEnd(Animation animation) 
        {
            image.clearAnimation();
            image.invalidate();
            pause(image);

        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub

        }
    });
}    
public void pause (final ImageView image)
{
    Animation anim = new AlphaAnimation(1, 1);

    anim.setDuration(2000);

    image.startAnimation(anim);
    anim.setAnimationListener(new AnimationListener() {
        public void onAnimationEnd(Animation animation) 
        {
            image.clearAnimation();
            image.invalidate();
            fadeout(image);

        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub

        }
    });
}     
public void fadeout (final ImageView image)
{
    Animation anim = new AlphaAnimation(1,0);

    anim.setDuration(2000);

    image.startAnimation(anim);
    anim.setAnimationListener(new AnimationListener() {
        public void onAnimationEnd(Animation animation) 
        {
            image.clearAnimation();
            image.invalidate();
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub

        }
    });
}    

Wyraźna animacja i unieważnienie, gdzie tylko poprzednie próby i doprowadzenie tego do prawidłowego działania. Nie wiem, czy są wymagane, czy nie.

Mam nadzieję, że to komuś pomoże.


Ryan

testowanie
źródło
1

mam to do zrobienia ... próbowałem uzyskać widok obracający się w kółko w sposób ciągły.

poprzedni używałem Rotation.setRepeatMode (-1), ale to nie zadziałało. przełączony na setrepeatcount i działa. To jest na galarecie 4.2.2

 ObjectAnimator rotation = ObjectAnimator.ofFloat(myview,
                          "rotation", 360).setDuration(2000);
                rotation.setRepeatMode(-1);
          rotation.setRepeatCount(Animation.INFINITE); 
 rotation.start();
j2emanue
źródło
0

Napotkałem ten sam problem, ale nie chciałem wykonywać żadnych czynności związanych z synchronizacją w Javie, ponieważ wątek interfejsu użytkownika może być czasami bardzo zajęty. Flaga INFINITE nie działa dla zestawu tagów. Więc rozwiązałem problem za pomocą małego fragmentu kodu:

mAnimation = (AnimationSet) AnimationUtils.loadAnimation(myContext, R.anim.blink);
mIcon.startAnimation(mAnimation);
mAnimation.setAnimationListener(new AnimationListener() {
    public void onAnimationStart(Animation animation) {}
    public void onAnimationRepeat(Animation animation) {}
    public void onAnimationEnd(Animation animation) {
        mIcon.startAnimation(mAnimation);
    }
});

z następującym kodem XML:

<alpha
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="0.0"
    android:toAlpha="1.0" />

<alpha
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="0.9"
    android:startOffset="1000"
    android:toAlpha="0.0" />

Gdzie mIcon to ImageView z mojego układu.

Jordi
źródło
0

Rozwiązałem ten problem. To jest moja wersja poprawki:

public class HelloAndroidActivity extends Activity {
private static String TAG = "animTest";
private Animation scaleAnimation;
private int currentCover = 0;
private List<ImageView> imageViews = new ArrayList<ImageView>(3);
private Button btn;
private ImageView img;

/**
 * Called when the activity is first created.
 * @param savedInstanceState If the activity is being re-initialized after 
 * previously being shut down then this Bundle contains the data it most 
 * recently supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it is null.</b>
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG, "onCreate");
    setContentView(R.layout.test);

    img = (ImageView)findViewById(R.id.testpict);
    imageViews.add(img);
    img = (ImageView)findViewById(R.id.testpictTwo);
    imageViews.add(img);
    img = (ImageView)findViewById(R.id.testpict3);
    imageViews.add(img);

    scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.photo_scale);
    scaleAnimation.setAnimationListener(new CyclicAnimationListener());

    btn = (Button)findViewById(R.id.startBtn);
    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            imageViews.get(0).startAnimation(scaleAnimation);
        }
    });



}

private class CyclicAnimationListener implements AnimationListener{

    @Override
    public void onAnimationEnd(Animation animation) {
        currentCover += 1;
        if(currentCover >= imageViews.size()){
            currentCover = 0;
        }
        img = imageViews.get(currentCover);
        scaleAnimation = AnimationUtils.loadAnimation(HelloAndroidActivity.this, R.anim.photo_scale);
        scaleAnimation.setAnimationListener(new CyclicAnimationListener());
        img.startAnimation(scaleAnimation);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        Log.d("Animation", "Repeat");
    }

    @Override
    public void onAnimationStart(Animation animation) {

    }

}

}
xander_blr
źródło
0

Właśnie natknąłem się na ten problem podczas pracy nad aplikacją kompatybilną wstecz. bardzo frustrujące! Skończyło się na tym, że napisałem fajną klasę obejścia, którą można wywołać z onCreate i która uruchomi dowolny zasób animacji w nieokreśloną pętlę.

klasa AnimationLooper jest dostępna tutaj: https://gist.github.com/2018678

newbyca
źródło
0

Po zapoznaniu się z odpowiedziami z internetu znalazłem rozwiązanie, które działa idealnie dla mnie. (I tak, repeatCount i repeatMode są bardzo błędne, gdy są używane razem z animationSet).

anim_rotate_fade.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:ordering="together" >

    <objectAnimator
        android:duration="3000"
        android:propertyName="rotation"
        android:repeatCount="1"
        android:valueTo="360"
        android:valueType="floatType" />

    <objectAnimator
        android:duration="3000"
        android:propertyName="alpha"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:valueFrom="0.0"
        android:valueTo="0.3"
        android:valueType="floatType" />

    <objectAnimator
        android:duration="3000"
        android:propertyName="y"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:valueFrom="380"
        android:valueTo="430"
        android:valueType="floatType" />

</set>

W aktywności: (Rozwiąż to, wprowadzając niewielkie opóźnienie po zakończeniu animacji).

ImageView starlightImageView = new ImageView(this);
starlightImageView.setImageResource(R.drawable.starlight);
final AnimatorSet animate = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.anim.anim_rotate_fade);
AnimatorListenerAdapter animatorListener = new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        new Handler().postDelayed(new Runnable() {
            @Override public void run() {
                animate.start();
            }
        }, 1000);
    }
};
animate.setTarget(starlightImageView);
animate.addListener(animatorListener);

Jest wiele klas, które chciałbyś zbadać, ale obecnie używam obiektu ObjectAnimator, który jest bardzo elastyczny. Nie polecałbym używania Animation lub AnimationUtils:

  • Animacja
  • AnimationUtils
  • Animator
  • AnimatorInflater
  • AnimatorListener
  • AnimatorListenerAdapter
morph85
źródło
0

Należy posłuchać zakończenia pierwszej animacji, a następnie ponownie uruchomić animację w onStopAnimation oddzwonić, wypróbuj ten link

Ravi K. Sharma
źródło
0

Mała poprawka w odpowiedzi @Danufr, aby zaoszczędzić zasoby przed ponownym załadowaniem.

    operator = (ImageView) findViewById(R.id.operator_loading);
  final  Animation ani = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.finding_operator);


    ani.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {

            operator.startAnimation(ani);

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

    operator.setAnimation(ani);
Panie Coder
źródło
0

Rozwiązałem ten problem za pomocą wątku.

Button btn = (Button) findViewById(R.id.buttonpush);
    final TextView textview = (TextView) findViewById(R.id.hello);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            textview.setText("...................");
            final Animation animationtest = AnimationUtils.loadAnimation(MainActivity.this, android.R.anim.slide_in_left);
            animationtest.setDuration(1000);

            final Handler handler = new Handler();
            Runnable runnable = new Runnable() {
                public void run() {
                    handler.postDelayed(this, 1500);
                    textview.startAnimation(animationtest);
                }
            };
            handler.postDelayed(runnable, 500); // start
            handler.removeCallbacks(runnable); //STOP Timer

        }
    });
nikeru8
źródło
0

działa dobrze

 GifDrawable gifDrawable = (GifDrawable) gifImageView.getDrawable();
    gifDrawable.setLoopCount(0);
BHAVIK PANCHAL
źródło
0

Żadne z powyższych rozwiązań nie zadziałało w moim przypadku. Rozwiązanie autorstwa Danuofr działało w przypadku zestawu animacji, ale kiedy wykonywałem testy jednostkowe, moje testy utknęły w tej nieskończonej pętli. Wreszcie, specyficznie dla mojego przypadku, musiałem powtórzyć tę animację określoną liczbę razy. Więc ręcznie dodałem kopie mojej animacji w anim_rot.xml w sposób kaskadowy, dodając wartość przesunięcia . Wiem, że jest to złe i nie zadziała dla wielu, ale to było jedyne obejście w moim przypadku.

anim_rot.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="2000"
        android:fromDegrees="20"
        android:pivotX="29%"
        android:pivotY="50%"
        android:toDegrees="-20" />
    <rotate
        android:duration="2000"
        android:fromDegrees="-20"
        android:pivotX="29%"
        android:pivotY="53%"
        android:startOffset="2000"
        android:toDegrees="20" />
    <rotate
        android:startOffset="4000"
        android:duration="2000"
        android:fromDegrees="20"
        android:pivotX="29%"
        android:pivotY="56%"
        android:toDegrees="-20" />
    <rotate
        android:duration="2000"
        android:fromDegrees="-20"
        android:pivotX="29%"
        android:pivotY="59%"
        android:startOffset="6000"
        android:toDegrees="20" />
    <rotate
        android:startOffset="8000"
        android:duration="2000"
        android:fromDegrees="20"
        android:pivotX="29%"
        android:pivotY="62%"
        android:toDegrees="-20" />
    <rotate
        android:duration="2000"
        android:fromDegrees="-20"
        android:pivotX="29%"
        android:pivotY="65%"
        android:startOffset="10000"
        android:toDegrees="20" />
</set>

Zrobiłem to, aby powtórzyć animację 3 razy. Możesz dodać więcej kopii, aby powtórzyć to w określonym czasie, dodając wartości przesunięcia.

Sachin Aggarwal
źródło
-1

Spróbuj dodać kod do wątku pętli lub instrukcji while / for

carefacerz
źródło
Cóż, jedynym rozwiązaniem, które znalazłem, jest unikanie używania set tagów.
Pavel Chernov