I want to an animation that infinitely moves images up and down. However when I run my code, the animation only happens once. This is the animation xml:
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:repeatCount="3"
android:repeatMode="restart">
<!-- move down -->
<translate
android:fromYDelta="0%"
android:toYDelta="50%"
android:duration="1500"
android:fillAfter="true"/>
<!-- move up -->
<translate
android:fromYDelta="0%"
android:startOffset="1500"
android:toYDelta="-50%"
android:duration="1500"
android:fillAfter="true"/>
<!-- continue to move up -->
<translate
android:fromYDelta="0%"
android:startOffset="3000"
android:toYDelta="-20%"
android:duration="600"
android:fillAfter="true"/>
<!-- down to original pos -->
<translate
android:fromYDelta="0%"
android:startOffset="3600"
android:toYDelta="20%"
android:duration="600"
android:fillAfter="true"/>
</set>
This is my java code:
public class MainActivity extends AppCompatActivity {
Animation move1, move2, move3, move4, move5;
Button login;
ImageView bar1, bar2, bar3, bar4, bar5;
int delay1 = 500;
int delay2 = 1560;
int delay3 = 2300;
int delay4 = 3065;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
login = findViewById(R.id.btLogin);
bar1 = findViewById(R.id.ivBar1);
bar2 = findViewById(R.id.ivBar2);
bar3 = findViewById(R.id.ivBar3);
bar4 = findViewById(R.id.ivBar4);
bar5 = findViewById(R.id.ivBar5);
move1= AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move);
move2= AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move);
move3= AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move);
move4= AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move);
move5= AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move);
bar1.startAnimation(move1);
Handler handler = new Handler();
handler.postDelayed(() -> bar2.startAnimation(move2), delay1);
handler.postDelayed(() -> bar3.startAnimation(move3), delay2);
handler.postDelayed(() -> bar4.startAnimation(move4), delay3);
handler.postDelayed(() -> bar5.startAnimation(move5), delay4);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
}
Why doesn’t it repeat infinelty? Does it have something to do with the fill-after attribute in xml? Help would be greatly appreciated, its for a class project.
2
Answers
Remove
android:fillAfter="true"
from your animation XML and setandroid:repeatCount="infinite"
in the parent<set>
tag instead ofrepeatCount="3"
. ThefillAfter
was keeping each animation in its final state, preventing proper looping.That’s all you need to make it loop infinitely.
You should change
countRepeat
attribute to valueinfinite
. And move it into the firsttranslate
tag.