在Android中使用动画将ImageView移动到不同的位置

27

我有几个ImageView在一个RelativeLayout中。

当用户点击任何一个ImageView时,我希望使用微妙的动画将ImageView移动到指定位置。

例如:我最初设置了与ImageView相关联的LayoutParams的边距为layoutparams1.setMargins(90,70,0,0);,然后将其添加到布局中。

当用户点击ImageView时,我想要它的新位置是200,200,并且需要通过动画来完成。

所以,这可能吗?如果是,怎么做呢?

请注意,我通过编程方式创建了RelativeLayout及其所有子ImageView。

由于我是Android开发的新手,所以期望得到详细的答复。

5个回答

56
TranslateAnimation animation = new TranslateAnimation(0, 50, 0, 100);
animation.setDuration(1000);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener());

imageView.startAnimation(animation);

更新: 问题在于View仍然处于旧位置。因此,当动画完成时,我们必须将其移动到新位置。为了检测动画何时完成,我们必须创建自己的animationListener(在activity类中):

private class MyAnimationListener implements AnimationListener{

    @Override
    public void onAnimationEnd(Animation animation) {
        imageView.clearAnimation();
        LayoutParams lp = new LayoutParams(imageView.getWidth(), imageView.getHeight());
        lp.setMargins(50, 100, 0, 0);
        imageView.setLayoutParams(lp);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationStart(Animation animation) {
    }

}

因此,onClickEvent将在其新位置再次触发。 动画将向下移动更多,因此您可能希望将xy保存在变量中,以便在onAnimationEnd()中将其移动到固定位置。

2
可以工作!但是在ImageView的新位置,它不会响应任何点击事件,而且如果我点击它之前的位置,另一个相同的ImageView实例会动画化。有什么办法可以修复它吗? - Kushal
非常感谢!但是在onAnimationEnd()中重新定位会导致ImageView闪烁一次。 :-/ - Kushal
1
在设置 LayoutParms 之前,您必须清除动画(请参见上文)。 - D-32
我认为你应该使用LinearLayout.LayoutParams而不是仅使用LayoutParams,否则setMargins()将不可用。 - Pratik Butani
1
只需补充一下,如果您将setFillAfter设置为true而不是false,则无需在动画结束后手动设置边距。animation.setFillAfter(false); -> animation.setFillAfter(true); - Abhishek Patidar
https://dev59.com/fl4d5IYBdhLWcg3wDe30#70812265 - Sachin Singh

10

最好使用 ObjectAnimator ,它可以将 ImageView 实际移动到新位置。
例如:

ImageView splash;

@Override
public boolean onTouchEvent(MotionEvent event) {
    float tx = event.getX();
    float ty = event.getY();

    int action = event.getAction();
    switch(action) {
        case MotionEvent.ACTION_DOWN:
            tx = event.getX();
            ty = event.getY();

            // findViewById(R.id.character).setX(tx-45);
            // findViewById(R.id.character).setY(ty-134);

            ObjectAnimator animX = ObjectAnimator.ofFloat(splash, "x", tx-45);
            ObjectAnimator animY = ObjectAnimator.ofFloat(splash, "y", ty-134);
            AnimatorSet animSetXY = new AnimatorSet();
            animSetXY.playTogether(animX, animY);
            animSetXY.start();

            break;
        default:
    }
    return true;
}

实际上,我最喜欢这个。 - creativecreatorormaybenot

6

2
在下面的代码中,我正在动态地在FrameLayout中添加一个ImageView。添加后,我增加了缩放并设置了alpha值以产生缩放效果,在完成动画后,我只是将我的ImageView从一个位置平移到另一个位置。
在Framelayout上添加ImageView。
    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);

在图像视图上添加动画
       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();

0

你可以使用这段代码 :)

 private void animeView(View imageView){

        Handler handler = new Handler();
        final int[] deltaX = {50};
        final int[] deltaRotation = {45};
        handler.postDelayed(new Runnable() {
             @Override
             public void run() {
                 imageView.animate().translationX(deltaX[0])
                                    .rotation(deltaRotation[0]).setDuration(1000) ;
                 deltaX[0] *=-1 ;
                 deltaRotation[0] *=-1 ;
                 handler.postDelayed(this , 1000);
             }
         },1000);

    }

虽然这段代码可能回答了问题,但最好包含一些上下文,解释它的工作原理以及何时使用它。仅有代码的答案从长远来看并不有用。 - Abhishek Dutt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接