Android:在动画完成后更新LinearLayout位置

3
任何关于以下问题的帮助都将不胜感激。我知道我需要做什么,并且已经查阅了开发人员文档,但我需要使用的确切语法却让我无从下手(我是一个新手)。
这是我的操作步骤。我在res/anim中有一个名为translate.xml的文件,它运行良好,内容如下:
<translate xmlns:android="http://schemas.android.com/apk/res/android" 
   android:fromXDelta="0%" 
   android:toXDelta="0%" 
   android:fromYDelta="0%" 
   android:toYDelta="10%" 
   android:repeatCount="0" 
   android:duration="1000" 
   android:fillEnabled="true" 
   android:fillAfter="true"/>

我将代码执行方式如下:

我像这样执行我的代码:

    l = (LinearLayout) findViewById(R.id.linearLayout1);
    a = AnimationUtils.loadAnimation(this, R.anim.translate);
    a.setAnimationListener(new AnimationListener() {
        public void onAnimationStart(Animation anim){};
        public void onAnimationRepeat(Animation anim){};
        public void onAnimationEnd(Animation anim){
            //l.setLayoutParams(params);
        };
    });
l.startAnimation(a);

当动画完成时,我希望被动画移动的LinearLayout能够移动到它的新位置。这是因为该LinearLayout包含了用户可以互动的多个表单元素。
这是一个相当简单的项目中的一个简单的动画。它只把元素向下移动了约30个像素。如果没有遇到问题,我不会寻求帮助。但是我已经挣扎了几个小时了。我知道需要在动画结束时更新LinearLayout的参数,但具体如何做呢?我看过好几种方法,但都有点令人困惑。
提前感谢您的帮助。
2个回答

0

不要创建新的AnimationListener,而是尝试将AnimationListener接口实现到您当前(或新的)类中。然后只需覆盖onAnimationEnd()方法。

示例:

public class ThisClass implements AnimationListener {

      private otherMethod() {
          l.getAnimation().setAnimationListener(this);
      }

      public void onAnimationStart(Animation anim){};
      public void onAnimationRepeat(Animation anim){};
      public void onAnimationEnd(Animation anim){
          l.setLayoutParams(params);
      };

}


那似乎是有道理的。我按照你的指示使用AnimationListener扩展了类,并添加了必要的监听器方法。除了在onAnimationEnd方法中无法将“params”解析为变量之外。你的意思是什么?params会引用什么? - user722826
l.getAnimation().setAnimationListener(this); 这行代码导致我的应用程序崩溃 :-( - user722826
你需要创建一个新的LayoutParams变量,或者将其创建为该类的公共变量。它为什么会崩溃(logcat上写了什么)? - John Leehey
a.setAnimationListener(this);我困惑的是设置LayoutParams并传递值。我不知道如何定位新位置以设置我的LinearLayout,或者这是否是我应该做的。 - user722826

0

终于找到了一个解决方法,正确的做法是setFillAfter(true)

如果你想在xml中定义动画,那么你应该像这样做一些事情

<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@android:anim/decelerate_interpolator"
     android:fillAfter="true">

    <translate 
        android:fromXDelta="0%"
        android:toXDelta="-100%"
        android:duration="1000"/>

</set>

您可以看到,我在set标签中定义了filterAfter="true"。如果您尝试在translate标签中定义它,它将不起作用,可能是框架中的错误

然后,在代码中:

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out);
someView.startAnimation(anim);

OR

TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0);

            animation.setFillAfter(true);

            animation.setDuration(1800);

            someView.startAnimation(animation);

那么它肯定会起作用的!!

现在这有点棘手,似乎视图实际上是移动到了新位置,但实际上是视图的像素被移动了,也就是说,您的视图实际上处于其初始位置,但不可见。如果您的视图中有一些按钮或可点击的视图(在我的情况下是布局),为了修复它,您必须手动将您的视图/布局移动到新位置。

public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)

new TranslateAnimation(-90, 150, 0, 0);

现在我们可以看到,我们的动画将从-90 x轴开始到150 x轴结束

所以我们要做的就是设置

someView.setAnimationListener(this);

并且在

public void onAnimationEnd(Animation animation)
{
   someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight());
}

现在让我来解释一下public void layout (int left, int top, int right, int bottom)

它可以将你的布局移动到一个新的位置,第一个参数定义了左边界,我们这里是150,因为平移动画已经将我们的视图动画到了150 x-axistop是0,因为我们还没有对y轴进行平移动画。现在,在右侧,我们已经执行了someView.getWidth() + 150,基本上我们获得了视图的宽度,并加上了150,因为我们的左侧现在已经移动到150 x-axis,以将视图的宽度恢复到原始值,而底部等于我们视图的高度。

我希望你们现在理解了翻译的概念,如果你们还有任何问题,请在评论区提问,我很乐意帮助 :)

编辑 不要使用layout()方法,因为每当视图被无效化时,框架都会调用它,而你所做的更改不会持久保存,请根据你的需求使用LayoutParams设置你的布局参数。


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