There is an image of a handful of gold, there is an animated opening chest. When you click on a handful, it should turn into a handful of coins and fly into the chest. What is the best way to animate these coins? Each downloaded as an ImageView and separately animated?

Reply to comment:

  1. I am still a beginner, and I use only ConstraintLayout, after the lessons it was like this. Do I have to redo everything on Relative?
  2. I do not need to inherit your class from AppCompatActivity, just carry out the necessary imports?
  3. The paddings parameter in R.dimen.paddings is highlighted in red.
  4. Here with this line got confused.
    ((parent type startView) startView.getParent) .removeView (startView);

Changed it like this:

((ImageView) startView.getParent ()). RemoveView (startView);

but now removeView () is red.

  1. When implementing a class, my main class requires you to declare abstract or implement the abstract method AnimationEnd (int)

    1 answer 1

    I use for such purposes (in my case - points are “flying”) the class is lower.

    Use: where it is necessary for each heap, create an instance of it and transfer the context, RelativeLayout (yes, it is necessary that the root View activity be RelativeLayout . You can FrameLayout ), an image that starts the movement (your heap, wherever it is), an image of the chest ( where the money will fly)), the amount that will "fly" (the amount of money).

     public class AnimateScore { private static final int ANIMATION_DURATION = 400; private View targetView; private int offset, number; private AnimationEnd animationEnd; private ImageView img; private RelativeLayout container; interface AnimationEnd { void animationEnd(int number); } AnimateScore(Context ctx, RelativeLayout container, View startView, View targetView, int number) { animationEnd = (AnimationEnd) ctx; this.number = number; int dimens = (int) ctx.getResources().getDimension(R.dimen.paddings); offset = (int) (-24 * ctx.getResources().getDisplayMetrics().density); this.container = container; this.targetView = targetView; img = new ImageView(ctx); int[] coords = {getRelativeLeft(startView), getRelativeTop(startView)}; String str = "+" + String.valueOf(number); img.setImageResourse(R.drawable.my_img) img.setPadding(dimens, dimens, dimens, dimens); img.setX(coords[0] + dimens * 2); img.setY(coords[1]); ((тип parent startView)startView.getParent).removeView (startView); container.addView(img); img.postDelayed(new Runnable() { @Override public void run() { drawAnimation(img); } }, 10); } private void drawAnimation(View v1) { v1.clearAnimation(); ScaleAnimation animation = new ScaleAnimation (1, 0,1,0); animation.setDuration(ANIMATION_DURATION + 100); animation.setFillAfter(true); v1.setAnimation(animation); v1.startAnimation(animation); v1.animate().translationX(getRelativeLeft(targetView)) .translationY(getRelativeTop(targetView) + offset).setDuration(ANIMATION_DURATION) .setInterpolator(new DecelerateInterpolator()).setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { container.removeView(img); animationEnd.animationEnd(number); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } private int getRelativeLeft(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getLeft(); else return myView.getLeft() + getRelativeLeft((View) myView.getParent()); } private int getRelativeTop(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getTop(); else return myView.getTop() + getRelativeTop((View) myView.getParent()); } } 

    offset - for correct operation (I don’t know where the offset comes from, but so)

    dimens*2 - to allow for two parental padding

    in receiver class don't forget implements AnimateScore.AnimationEnd

    adapted a little class for the answer, if something does not work or have a question - write in the comments;)

    Time:

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/globalCont" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.constraint.ConstraintLayout...> </android.support.constraint.ConstraintLayout> </RelativeLayout> 

    Two: no, just call the instance at the right time: new AnimateScore (YourActivity.this, findViewById(R.id.globalcont),your_coin_pile_img,your_chest_img, 100)

    Three: these are indents, prescribed in my in dimen . This can be deleted or move the cursor there, press alt + enter and enter a value (usually 5-10-15dp). Or register in dimen manually.

    Four: "type of parent" - the type of container in which your "pile of gold" lies (LinearLayout, FrameLayout, ConstrainLayout, etc.)

    Five: implement :) (alt + enter, when the cursor is on red). Optional part, you can remove along with the interface . It is necessary in order to keep track of when the animation is “reached” and, for example, only then add coins to the chest.

    • Thank you Now I will write questions in the edited post, otherwise it is inconvenient. - keltkelt
    • one
      @keltkelt, updated the answer - Jarvis_J
    • Swears on findViewById (R.id.globalcont), says that this is a View, and he is looking for RelativeLayout. - keltkelt
    • It seems to have taken when I first did so RelativeLayout rel = findViewById (R.id.globalCont); It is strange why she did not immediately accept. - keltkelt
    • one
      @keltkelt, so as not to jump try to remove the offset or dimens. And, perhaps, as a targetView, you are not sending a chest, but something else. Or the coordinates of your chest occupy the entire screen. If you need to move only on one axis (down), translateX can also be removed. - Jarvis_J