0

I'm new to android studio and I want to animate an imageButton with a sequential animation set. The animation set (animation_boutons.xml)is in res/anim. I've tried with animationSet in java but the app crashed every time I launched the emulator. I've spent a long time looking for a solution. I hope someone can help me ! I apologize if it's something obvious.

java code:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        configureCodeurBouton();
    }
    private void configureCodeurBouton() {
        ImageButton boutonCodeur = findViewById(R.id.boutoncodeur);
        Animation animBoutons = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_boutons);
        animBoutons.setRepeatCount(Animation.INFINITE);
        boutonCodeur.setAnimation(animBoutons);
        boutonCodeur.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this, codeur.class));
            }
        });
    }
}

xml code:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:fillAfter="true">

    <rotate

        android:fromDegrees="0"
        android:toDegrees="20"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="0"
        android:duration="1000"
        />

    <rotate
        android:startOffset="1000"
        android:fromDegrees="20"
        android:toDegrees="-20"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="2000"
        />

    <rotate

        android:fromDegrees="-20"
        android:toDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="3000"
        android:duration="1000"
        />

</set>

Also, Vedprakash Wagh give me the advice to try animBoutons.setRepeatCount(Animation.INFINITE) but it has no effect).

2 Answers2

0

Your app is crashing every time because you're trying to find your ImageButton when the class is created first, and not after the layout is set.

You're getting NullPointerException, as there is no ImageButton with id R.id.boutoncodeur in your View hierarchy when you're trying to find it.

You need to find your ImageView AFTER it is available in your View hierarchy i.e. after your setContentView();

You can either do this:

  1. Remove your second line

    ImageButton boutonCodeur = findViewById(R.id.boutoncodeur);
    

    as you've already found your ImageView in your configureCodeurButton() function.

  2. Or, you can keep one class variable of ImageView, and make findViewById call after setContentView like below.

    public class MainActivity extends AppCompatActivity {
    ImageButton boutonCodeur;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        boutonCodeur = findViewById(R.id.boutoncodeur);
        configureCodeurBouton();
    }
    private void configureCodeurBouton() {
        Animation animBoutons = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_boutons);
        boutonCodeur.setAnimation(animBoutons);
        boutonCodeur.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this, codeur.class));
            }
        });
    }
    }
    

You can learn more about NullPointerException here. Also, learn how to read the errors from tutorials that are available. Or, simply open the logcat tab in Android Studio when the error occurs to know what Error you're getting.

  1. To make your animation run infinitely, you can add this in your code.

animation.setRepeatCount(Animation.INFINITE)

Vedprakash Wagh
  • 3,595
  • 3
  • 12
  • 33
  • Thank you for your answer. I fixed that on the post and I learned something. However, do you have an idea for my problem ? (make the animation infinite) – Black Emc2 Jun 08 '19 at 22:00
  • I've updated my answer, please check it out. If it helped you, don't forget to mark it as accepted – Vedprakash Wagh Jun 09 '19 at 04:56
  • No it doesn't work. The animation launches one time and then stops. I tried with another value than Animation.INFINITE too (like 15) to see if the argument was the problem, but it has no effect. I think the fact it is an animation set blocks this method. – Black Emc2 Jun 09 '19 at 08:19
  • add android:repeatCount="infinite" to all your rotate animations and remove setrepeat count from code – Vedprakash Wagh Jun 09 '19 at 10:55
  • I tried that but it doesn't work as expected. Every rotate animation restarts alone and the full animation is bugged. At least it is infinite. Any other idea ? Also, when I open a new activity and then come back, the bugged animation doesn't work. – Black Emc2 Jun 09 '19 at 12:14
  • I figured out a solution. It's way simpler. I changed the whole xml file to have only on rotate animation and I set `android:repeatCount="infinite"` and `android:repeatMode="reverse"`. The repeatMode allows me to do the animation backwards and not to have a sequential animation. Thank you for your time and help ! – Black Emc2 Jun 09 '19 at 12:24
0

I just had to change the whole xml anim_boutons file so I have only one animation and not three rotate animations. the repeatMode line says to repeat the animation backwards at each repeat. This gives the expected effect.

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:fillAfter="true">

    <rotate

        android:fromDegrees="-20"
        android:toDegrees="20"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="0"
        android:duration="1000"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
    />

</set>