TranslateAnimation 完成后跳回起点

发布于 2024-12-12 03:58:16 字数 482 浏览 0 评论 0原文

我的 TranslateAnimation 可以工作,但在动画结束时,它会跳回原始位置。

        LinearLayout rl = (LinearLayout) findViewById(R.id.navPanel);

          animation = new TranslateAnimation(
              Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
              Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 3.0f
          );
          animation.setDuration(500);

          rl.startAnimation(animation);

我怎样才能让它停留在最终位置?

My TranslateAnimation works, but at the end of the animiation, it jumps back to the original location.

        LinearLayout rl = (LinearLayout) findViewById(R.id.navPanel);

          animation = new TranslateAnimation(
              Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
              Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 3.0f
          );
          animation.setDuration(500);

          rl.startAnimation(animation);

How can I make it stay at the end location?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

趁年轻赶紧闹 2024-12-19 03:58:16

旧的(3.0 之前的)动画 API 的行为有点奇怪 - 当它制作动画时,它只是转换视图的绘制位置,但实际上并不相对于其父视图移动视图。

为了让视图在动画完成时保持不动,您可以在 TranslateAnimation 上设置一个 Animation.AnimationListener。在侦听器的 onAnimationEnd() 方法中,您可以通过操作视图上的 LayoutParams 将视图移动到其最终静止位置。

The old (pre-3.0) Animation API behaves a bit weird - when it's animating, it merely translates where the view is drawn, but doesn't actually move the view with respect to its parents.

In order to get the view to stay put when the animation is done, you can set an Animation.AnimationListener on your TranslateAnimation. In the onAnimationEnd() method of the listener, you move the view to its final resting place by manipulating the LayoutParams on the view.

淡水深流 2024-12-19 03:58:16

对动画使用 animation.setFillAfter(true) 使其在翻译结束时停止。

http://developer.android.com/reference/android/view/animation/ Animation.html#setFillAfter(布尔值)

use animation.setFillAfter(true) for your animation to stop it at the end of translation.

http://developer.android.com/reference/android/view/animation/Animation.html#setFillAfter(boolean)

凯凯我们等你回来 2024-12-19 03:58:16

同样的问题 https://stackoverflow.com/a/6519233/1253065

使用
动画.setFillAfter(true) , 动画.setFillEnabled(true)

this same problem https://stackoverflow.com/a/6519233/1253065

use
animation.setFillAfter(true) , animation.setFillEnabled(true)

独行侠 2024-12-19 03:58:16

为了避免重复代码,您可以子类化 AnimatorListenerAdapter 并创建您自己的 AnimatorListener 类,在动画之后重新附加视图,然后在需要的地方使用它而不是默认的 AnimatorListener。

类:

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

public class PersistViewAnimatorListener extends AnimatorListenerAdapter {

    private View view; // keep a reference to the view
    public PersistViewAnimatorListener(View view) {
        this.view = view;
    }

    @Override public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);

        // re-attach the view to its parent at its new location
        if (view == null) { return; } // defensive, the view may have been removed while it was animated, do nothing in this case

        ViewGroup parent = (ViewGroup) view.getParent(); // get the parent
        if (parent == null) { return; } // defensive
        int index = parent.indexOfChild(view); // get the index of the view
        parent.removeView(view); // remove the view

        if (parent.getClass().equals(RelativeLayout.class)) { // RELATIVE LAYOUT
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(view.getLayoutParams()); // add the view back at its index with new layout parameters
            layoutParams.setMargins(Math.round(view.getX()), Math.round(view.getY()), 0, 0); // left, top, right, bottom; round the float to int
            parent.addView(view, index, layoutParams);
        } else if (parent.getClass().equals(FrameLayout.class)) { // FRAME LAYOUT
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(view.getLayoutParams()); // the same for FrameLayout
            layoutParams.setMargins(Math.round(view.getX()), Math.round(view.getY()), 0, 0);
            parent.addView(view, index, layoutParams);
        } else { // currently no further layouts supported, implement these here
            throw new UnsupportedOperationException("PersistViewAnimatorListener is currently only supported where the parent is either RelativeLayout or FrameLayout.");
        }

        view.setTranslationX(0); view.setTranslationY(0); // reset translated values from the animation

    }
}

以及如何使用它:

view.animate().yBy(height).setListener(new PersistViewAnimatorListener(view)); // call your custom listener in .setListener() and pass in the view

该解决方案假设您使用relativelayout或framelayout作为父级。此外,它只关心位置,而不关心大小或其他可以设置动画的属性。

To avoid repetitive code, you can subclass the AnimatorListenerAdapter and create your own AnimatorListener class where you re-attach the view after the animation, then use it wherever needed instead of the default AnimatorListener.

The class:

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

public class PersistViewAnimatorListener extends AnimatorListenerAdapter {

    private View view; // keep a reference to the view
    public PersistViewAnimatorListener(View view) {
        this.view = view;
    }

    @Override public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);

        // re-attach the view to its parent at its new location
        if (view == null) { return; } // defensive, the view may have been removed while it was animated, do nothing in this case

        ViewGroup parent = (ViewGroup) view.getParent(); // get the parent
        if (parent == null) { return; } // defensive
        int index = parent.indexOfChild(view); // get the index of the view
        parent.removeView(view); // remove the view

        if (parent.getClass().equals(RelativeLayout.class)) { // RELATIVE LAYOUT
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(view.getLayoutParams()); // add the view back at its index with new layout parameters
            layoutParams.setMargins(Math.round(view.getX()), Math.round(view.getY()), 0, 0); // left, top, right, bottom; round the float to int
            parent.addView(view, index, layoutParams);
        } else if (parent.getClass().equals(FrameLayout.class)) { // FRAME LAYOUT
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(view.getLayoutParams()); // the same for FrameLayout
            layoutParams.setMargins(Math.round(view.getX()), Math.round(view.getY()), 0, 0);
            parent.addView(view, index, layoutParams);
        } else { // currently no further layouts supported, implement these here
            throw new UnsupportedOperationException("PersistViewAnimatorListener is currently only supported where the parent is either RelativeLayout or FrameLayout.");
        }

        view.setTranslationX(0); view.setTranslationY(0); // reset translated values from the animation

    }
}

And how you use it:

view.animate().yBy(height).setListener(new PersistViewAnimatorListener(view)); // call your custom listener in .setListener() and pass in the view

This solution assumes you are using RelativeLayout or FrameLayout for the parent. Also, it just cares about the position, not size or other properties that can be animated as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文