What's the correct way to animate a View from

2019-03-25 09:52发布

问题:

I would like to do the following. I have a set of buttons that have some icons on them. When the user taps one, I would like to introduce a new View that starts in the same coordinate as the tapped icon, and then that new View would shift over to some other location on the screen and when it arrived there be removed.

I know how to create a new view and add/remove it to the parent RelativeLayout (should it not be a RelativeLayout?) and all that. What I'm not clear on is how to get the absolute coordinates of the button that was tapped (since it's just one element inside a parent layout, inside another parent layout) and then set its coordinates and apply an animation, and then what would notify me that it has arrived where it was going, so that I can remove it?

Can't find an example of how to do this anyway, so, hoping someone can point me in the right direction.

回答1:

So, it turns out that this is much more straight forward than I imagined.

I created a full screen RelativeLayout that I only show while the animation is happening.

I get the starting position of my burried button like this (it's funny to see these C style coding mechanisms in Java, they're pretty rare these days:

int fromLoc[] = new int[2];
v.getLocationOnScreen(fromLoc);     
float startX = fromLoc[0];
float startY = fromLoc[1];

So, now I have my starting point.

My end point is an absolute coordinate on the screen, you can assign that however you wish

Then I make a little Animations helper class that lets me pass in all the coordinates, the callback, and the duration of the animation

    public class Animations {
public Animation fromAtoB(float fromX, float fromY, float toX, float toY, AnimationListener l, int speed){


        Animation fromAtoB = new TranslateAnimation(
                Animation.ABSOLUTE, //from xType
                fromX, 
                Animation.ABSOLUTE, //to xType
                toX, 
                Animation.ABSOLUTE, //from yType 
                fromY, 
                Animation.ABSOLUTE, //to yType 
                toY
                 );

        fromAtoB.setDuration(speed);
        fromAtoB.setInterpolator(new AnticipateOvershootInterpolator(1.0f));


        if(l != null)
            fromAtoB.setAnimationListener(l);               
                return fromAtoB;
    }
}

and we need a listener to let us know when the animation is done to clear it

 AnimationListener animL = new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {     
        }

        @Override
        public void onAnimationRepeat(Animation animation) {        
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            //this is just a method to delete the ImageView and hide the animation Layout until we need it again.
            clearAnimation();       
        }
    };

And lastly we throw it all together and press GO

int fromLoc[] = new int[2];
    v.getLocationOnScreen(fromLoc);     
    float startX = fromLoc[0];
    float startY = fromLoc[1];      
    RelativeLayout rl = ((RelativeLayout)findViewById(R.id.sticker_animation_layout));
    ImageView sticker = new ImageView(this);

    int stickerId = getStickerIdFromButton(v);
    if(stickerId == 0){
        stickerAnimationPlaying = false;
        return;         
    }

    float destX = 200.0f;//arbitrary place on screen
    float destY = 200.0f;//arbitrary place on screen

    sticker.setBackgroundResource(stickerId);
    sticker.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    rl.addView(sticker);
    Animations anim = new Animations();
    Animation a = anim.fromAtoB(startX, startY, destX, destY, animL,750);
    sticker.setAnimation(a);
    a.startNow();


回答2:

I am just add my view on center position on frame layout and translation my view to x-axis and y-axis. Try below code:-

Add image view on framelayout

    imgHeart = new ImageView(getBaseContext());
    imgHeart.setId(R.id.heartImage);
    imgHeart.setImageResource(R.drawable.material_heart_fill_icon);
    imgHeart.setLayoutParams(new FrameLayout.LayoutParams(50, 50, Gravity.CENTER));
    mainFrameLaout.addView(imgHeart);

Add animation on image view

       imgHeart.animate()
            .scaleXBy(6)
            .scaleYBy(6)
            .setDuration(700)
            .alpha(2)
            .setListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    imgHeart.animate()
                            .scaleXBy(-6f).scaleYBy(-6f)
                            .alpha(.1f)
                            .translationX((heigthAndWidth[0] / 2) - minusWidth)
                            .translationY(-((heigthAndWidth[1] / 2) - minusHeight))
                            .setDuration(1000)
                            .setListener(new Animator.AnimatorListener() {
                                @Override
                                public void onAnimationStart(Animator animation) {
                                }

                                @Override
                                public void onAnimationEnd(Animator animation) {
                                // remove image view from framlayout
                                }
                                @Override
                                public void onAnimationCancel(Animator animation) {
                                }

                                @Override
                                public void onAnimationRepeat(Animator animation) {
                                }
                            }).start();
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            }).start();


回答3:

You can use Android transition animation to move a view over the layout. Have a look at the below mentioned link to get some ideas on animating views inside the layout.

https://github.com/lgvalle/Material-Animations