Страницы

Поиск по вопросам

четверг, 16 мая 2019 г.

Как лучше сделать анимацию нескольких монеток, которые уменьшаясь, летят в одну точку?

Есть изображение кучки золота, есть анимированный открывающийся сундук. При нажатии на кучку, она должна превратиться в горсть монеток и полететь в сундук. Каким образом лучше сделать анимацию этих монеток? Каждую загрузить как ImageView и отдельно анимировать?
Ответ на комментарий:
Я до сих пор новичок, и использую только ConstraintLayout, после уроков так повелось. Мне надо переделать все на Relative? Мне не нужно наследовать ваш класс от AppCompatActivity, только провести нужные импорты? Параметр paddings в R.dimen.paddings подсвечен красным. Вот с этой строчкой запутался. ((тип parent startView)startView.getParent).removeView (startView);
Изменил ее так:
((ImageView)startView.getParent()).removeView(startView);
но теперь removeView() красный.
При имплементации класса, мой главный класс требует обьявить абстрактным или имплементировать абстрактный метод AnimationEnd(int)


Ответ

Использую для подобных целей (в моем случае - "летят" очки) класс ниже.
Использование: где надо для каждой кучки создавайте его экземпляр и передавайте контекст, RelativeLayout (да, надо чтобы корневой View activity был RelativeLayout. Можно FrameLayout), изображение, с которого начинается движение (ваша кучка, где бы она не была), изображение сундука (куда полетят деньги)), количество, которое "долетит" (сумма денег).
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 - для корректной работы (не знаю откуда смещение, но так)
dimens*2 - чтобы учитывать два родительских padding
в классе-приёмнике не забудьте implements AnimateScore.AnimationEnd
немного адаптировал класс под ответ, если что-то не работает или есть вопрос - пишите в комментариях ;)
Раз:


Два: нет, просто в нужный момент вызывайте экземпляр: new AnimateScore (YourActivity.this, findViewById(R.id.globalcont),your_coin_pile_img,your_chest_img, 100)
Три: это отступы, прописанные у меня в dimen. Это можно удалить либо подвести туда курсор, нажать alt+enter и ввести значение (обычно 5-10-15dp). Либо прописать в dimen в ручную.
Четвере: "тип parent" - тип контейнера в котором лежит ваша "кучка золота" (LinearLayout, FrameLayout, ConstrainLayout и т.д.)
Пять: имплементируйте :) (alt+enter, когда курсор на красном). Необязательная часть, можете удалить вместе с interface. Нужна, для того, чтобы отслеживать, когда анимация "дошла" и, например, только тогда добавлять монеты в сундук.

Комментариев нет:

Отправить комментарий