简体   繁体   English

如何使用Android进行交互式动画(翻译)

[英]How to do interactive animation (translation) with Android

I have some png sequences in Android, that I need to animation their x and y postion translation from the top to the bottom of the screen. 我在Android中有一些png序列,我需要从屏幕的顶部到底部动画他们的x和y位置转换。 While the animation is occurring, I need the objects to receive click events. 在动画发生时,我需要对象来接收点击事件。

I understand this doesn't work really well in Android version before 3.0, since the display of the object is in a different place than the actual object so you don't get the click events mid-animation (which is what I need) since you aren't clicking on the object, only on the display. 我知道这在3.0之前的Android版本中效果不好,因为对象的显示位于与实际对象不同的位置,因此您不会在动画中期获得点击事件(这是我需要的)您不是仅在显示屏上单击该对象。

I'm doing something like this, and the animation looks fine, but I never get into the click handler: 我正在做这样的事情,动画看起来很好,但我从来没有进入点击处理程序:

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);
    }
});

What is the workaround to support interactive animations for devices before 3.0? 在3.0之前支持设备的交互式动画的解决方法是什么? Is there a custom animation class out there that will use a background thread to animate the x and y position of an object? 是否有一个自定义动画类,它将使用后台线程来设置对象的x和y位置的动画?

--update --- I tried using NineOldAndroid's solution, and the animation looks fine, but I'm not getting the onclick events during the animation. --update ---我尝试使用NineOldAndroid的解决方案,动画看起来很好,但我没有在动画期间获得onclick事件。 Here is my updated code. 这是我更新的代码。 So this works fine on ICS, but not on 2.3 Am I doing something wrong? 所以这在ICS上工作得很好,但在2.3上却没有。我做错了吗? or is the NineOldWorld's solution not actually changing the layout margins under the hood? 或者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);
                }
            });

-- Update #2 --- I also tried the path animation, but during the animation, and after, I'm not getting button click events. - 更新#2 ---我也尝试了路径动画,但在动画期间和之后,我没有得到按钮点击事件。 Anyone know what I'm doing wrong? 谁知道我做错了什么?

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();
    }
});

You're right, the issue is that pre-Honeycomb, only the visual aspect of your animating view is occurring. 你是对的,问题在于蜂窝前,只有动画视图的视觉方面正在发生。

This means that in addition to doing the "visual" animation, you also have to set/animate the frame/LayoutParams of the animated view. 这意味着除了执行“可视”动画之外,还必须设置动画视图的框架/ LayoutParams动画/动画。

For pre-Honeycomb devices, I find http://nineoldandroids.com/ very useful for listening to an animation which you can use for setting the LayoutParams of the view appropriately, but there are other examples as well, such as this one on SO: https://stackoverflow.com/a/3952933/429047 对于pre-Honeycomb设备,我发现http://nineoldandroids.com/非常适用于收听动画,您可以使用它来适当地设置视图的LayoutParams,但也有其他示例,例如SO上的这个: https//stackoverflow.com/a/3952933/429047

This is what I ended up doing, which works pretty well. 这就是我最终做的事情,效果非常好。

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

And here is my class: 这是我的班级:

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();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM