Страницы

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

воскресенье, 1 марта 2020 г.

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

#android


Есть изображение кучки золота, есть анимированный открывающийся сундук. При нажатии
на кучку, она должна превратиться в горсть монеток и полететь в сундук. Каким образом
лучше сделать анимацию этих монеток? Каждую загрузить как ImageView и отдельно анимировать?

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


Я до сих пор новичок, и использую только ConstraintLayout, после уроков так повелось.
Мне надо переделать все на Relative?  
Мне не нужно наследовать ваш класс от AppCompatActivity, только провести нужные импорты? 
Параметр paddings в R.dimen.paddings подсвечен красным. 
Вот с этой строчкой запутался.
((тип parent startView)startView.getParent).removeView (startView); 


Изменил ее так:

((ImageView)startView.getParent()).removeView(startView);

но теперь removeView() красный.


При имплементации класса, мой главный класс требует обьявить абстрактным или имплементировать
абстрактный метод AnimationEnd(int)

    


Ответы

Ответ 1



Использую для подобных целей (в моем случае - "летят" очки) класс ниже. Использование: где надо для каждой кучки создавайте его экземпляр и передавайте контекст, 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. Нужна, для того, чтобы отслеживать, когда анимация "дошла" и, например, только тогда добавлять монеты в сундук.

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

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