【问题标题】:Change position of view after end of animation动画结束后更改视图位置
【发布时间】:2013-12-05 20:22:40
【问题描述】:

我基于ViewGroup 开发了一个小部件,我的问题是我需要在动画结束后保存项目的位置。我在我创建的动画对象中调用了setFillAfter(true) AnimationListener 并在它的onAnimationEnd 方法中调用View.layout(l,t,r,b) 来设置动画后的位置,因为我希望动画下次从新项目的位置开始。但在这种情况下,看起来项目被布局了两次。如果我在动画结束时不使用View.layout(l,t,r,b),则下一个动画将从前一个位置开始。这是我的代码:

private void scrollUp() {
    for(int i = 0; i < getChildCount(); i++) {
        final View child = getChildAt(i);
        final int index = i; 
        final int newleft = child.getLeft() + mOffsetBetweenItems;
        final int newTop = child.getTop() - mOffsetBetweenItems;
        TranslateAnimation scrollUp = new TranslateAnimation(0, mOffsetBetweenItems, 0, -mOffsetBetweenItems);          
        scrollUp.setDuration(1500);
        scrollUp.setFillAfter(true);        
        scrollUp.setAnimationListener(
            new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {}

                @Override
                public void onAnimationRepeat(Animation animation) {}

                @Override
                public void onAnimationEnd(Animation animation) {
                    child.layout(newleft, newTop, newleft + child.getMeasuredWidth(), newTop + child.getMeasuredHeight() );
                }
            }
        );

        child.startAnimation(scrollUp);
    }
}

请给我一个建议,我应该如何根据动画的结束位置重置视图的位置?

【问题讨论】:

  • 改变位置意味着你想把它设置在布局的底部或顶部,你想要这样..
  • 不是 BOTTOM 或 TOP,而是由view.layout() 方法定义的具体 X、Y 坐标

标签: android android-animation


【解决方案1】:

您必须使用 ObjectAnimator ,它适用于 API 11 级别。它会自动更改视图位置,

这里是例子

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX);
objectAnimator.setDuration(1000);
objectAnimator.start();

感谢 JUL 的answer

如果找不到您的应用 object animator,请将 API 级别从 Project -&gt; properties -&gt; Android 更改为 import android.animation.ObjectAnimator;

【讨论】:

  • 它为视图设置动画。对象动画师不会更改视图坐标。
【解决方案2】:

我做到了。代码如下:

private void scrollUp() {
    for(int i = 0; i < getChildCount(); i++) {
        final View child = getChildAt(i);
        final int index = i; 
        final int newleft = child.getLeft() + mOffsetBetweenItems;
        final int newTop = child.getTop() - mOffsetBetweenItems;
        TranslateAnimation scrollUp = new TranslateAnimation(0, mOffsetBetweenItems, 0, -mOffsetBetweenItems);          
        scrollUp.setDuration(1500);
        scrollUp.setFillEnabled(true);        
        scrollUp.setAnimationListener(
            new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {}

                @Override
                public void onAnimationRepeat(Animation animation) {}

                @Override
                public void onAnimationEnd(Animation animation) {
                    child.layout(newleft, newTop, newleft + child.getMeasuredWidth(), newTop + child.getMeasuredHeight() );
                }
            }
        );

        child.startAnimation(scrollUp);
    }
}

刚刚删除setFillAfter(true) 并写setFillEnabled(true) 而不是。但在这种情况下,我不明白setFillEnabled() 工作的逻辑,因为它提供的行为不像文档中描述的那样。

【讨论】:

  • 在 onAnimationEnd 中设置新的左侧解决了我的问题。谢谢。在您的代码中,何时设置/更新 mOffsetBetweenItems?
  • 注意:至少在 Lollipop 上不起作用(猜测在某些 API 级别上它是偶然实现的,但肯定至少在 Lollipop 上不起作用)
【解决方案3】:

反转你的动画;首先为您的视图设置一个新位置,然后从旧位置动画到新位置。

【讨论】:

  • 如果我先给出一个新位置,它会立即在新位置重新绘制我的视图
  • 如果您在更改位置后立即调用 startAnimation() 则不会。
  • 如果我在view.startAnimation() 之前调用View.layout(),它会重绘我的视图并且动画从新位置开始
  • 啊,但是除了调用View.layout()之外,还有其他方法可以重新定位您的视图。我个人倾向于修改视图拥有的 LayoutParams。
  • LayoutParams 只允许您指向新的宽度和高度,但我还需要指向左侧和顶部坐标
猜你喜欢
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 2017-01-30
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多