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.