Как сделать интерактивную анимацию (перевод) с Android - PullRequest
3 голосов
/ 07 марта 2012

У меня есть несколько последовательностей png в Android, которые мне нужны для анимации их перемещения по x и y сверху вниз по экрану. Пока происходит анимация, мне нужны объекты для получения событий щелчка.

Я понимаю, что это не очень хорошо работает в версии Android до 3.0, поскольку отображение объекта находится в другом месте, чем реальный объект, поэтому вы не получите события щелчка в середине анимация (это то, что мне нужно), поскольку вы не нажимаете на объект, а только на дисплее.

Я делаю что-то вроде этого, и анимация выглядит нормально, но я никогда не попадаю в обработчик щелчков:

Animation animation = new TranslateAnimation(0, 20,0, 300);
animation.setDuration(1000);
ticket.startAnimation(animation);

ticket.startAnimation(animation);

ticket.setOnClickListener(new OnClickListener() {
    public void onClick(View view) {
            //I don't get into this click event during animation
        view.setVisibility(View.GONE);
    }
});

Какой обходной путь поддерживает интерактивные анимации для устройств до версии 3.0? Существует ли собственный класс анимации, который будет использовать фоновый поток для анимации положения объекта по осям x и y?

- обновление --- Я попытался использовать решение NineOldAndroid, и анимация выглядит нормально, но я не получаю события onclick во время анимации. Вот мой обновленный код. Так что это нормально работает на ICS, но не на 2.3 Я что-то не так делаю? или решение NineOldWorld на самом деле не меняет поля макета под капотом?

ImageView ticket = new ImageView(myActivity);
            ticket.setImageResource(R.drawable.ticket);
            ticket.setVisibility(View.INVISIBLE);
            ticketHolder.addView(ticket);
            ValueAnimator animation = ObjectAnimator.ofFloat(ticket, "y", 
                    -200f, ticketHolder.getHeight());
            animation.setDuration(3000);
            animation.start();
            animation.setStartDelay(i*1000);
            animationsMap.put(animation, ticket);

            ticket.setOnClickListener(new OnClickListener() {
                public void onClick(View view) {
                    view.setVisibility(View.GONE);
                }
            });

            animation.addListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator animation) {
//                    tickets.remove(((ObjectAnimator)animation).getTarget());
                    ImageView t = (ImageView) ((ObjectAnimator) animation).getTarget();
                    t.setVisibility(View.GONE);
                    animationsMap.remove(animation);
                    if(animationsMap.size() == 0){
                        ticketsAnimating = false;
                        scrim.setVisibility(View.VISIBLE);
                    }

                }
                @Override
                public void onAnimationStart(Animator animation){
                    ImageView t = (ImageView) ((ObjectAnimator) animation).getTarget();
                    t.setVisibility(View.VISIBLE);
                }
            });

- Обновление № 2 --- Я также пробовал анимацию пути, но во время анимации и после нее я не получаю события нажатия кнопки. Кто-нибудь знает, что я делаю не так?

mButton = (Button) findViewById(R.id.delete_me);
mButtonProxy = AnimatorProxy.wrap(mButton);

// Set up the path we're animating along
AnimatorPath path = new AnimatorPath();
path.moveTo(0, 0);
path.lineTo(0, 300);
path.curveTo(100, 0, 300, 900, 400, 500);

// Set up the animation
final ObjectAnimator anim = ObjectAnimator.ofObject(this, "buttonLoc",
        new PathEvaluator(), path.getPoints().toArray());
anim.setDuration(10000);

mButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d("united", "button clicked");
        anim.start();
    }
});

Ответы [ 2 ]

4 голосов
/ 07 марта 2012

Вы правы, проблема в том, что перед сотами происходит только визуальный аспект вашего анимационного представления.

Это означает, что в дополнение к «визуальной» анимации вы также должны установить / анимировать фрейм / LayoutParams анимированного представления.

Для устройств перед сотовой разверткой я нахожу http://nineoldandroids.com/ очень полезным для прослушивания анимации, которую можно использовать для правильной настройки LayoutParams вида, но есть и другие примеры, например, этот на SO: https://stackoverflow.com/a/3952933/429047

1 голос
/ 16 марта 2012

Это то, что я закончил, и это хорошо работает.

MyTranslateAnimation animation = new MyTranslateAnimation(ticket, 10, 100, -500, ticketHolder.getHeight());

А вот мой класс:

public class MyTranslateAnimation extends Animation {
        private float fromXDelta;
        private float fromYDelta;
        private float toXDelta;
        private float toYDelta;
        private View view;

        public MyTranslateAnimation(View view, float fromXDelta,
                float toXDelta, float fromYDelta, float toYDelta) {
            this.view = view;
            this.fromXDelta = fromXDelta;
            this.toXDelta = toXDelta;
            this.fromYDelta = fromYDelta;
            this.toYDelta = toYDelta;
        }

        @Override
        protected void applyTransformation(float interpolatedTime,
                Transformation t) {
            Log.d("united", "time " + interpolatedTime);
            float newX = (toXDelta - fromXDelta) * interpolatedTime;
            float newY = (toYDelta - fromYDelta) * interpolatedTime;
            LayoutParams p = (LayoutParams) view.getLayoutParams();
            p.leftMargin = (int) newX;
            p.topMargin = (int) newY;
            if (interpolatedTime > 0.0 && view.getVisibility() == View.GONE) {
                view.setVisibility(View.VISIBLE);
            }
            view.requestLayout();
        }
    }
...