在FrameLayout中快速切换和动画视图会使视图变得混乱

时间:2011-12-28 16:31:01

标签: android view android-animation

我对Android动画有一个非常奇怪的问题,我尝试了很多不同的方法和组件,但仍然找不到任何解释。

我有 FrameLayout ,它是视图的容器,还有按钮

FrameLayout 一次只能显示一个视图,当我点击按钮时,我希望FrameLayout 在FrameLayout的视图中显示另一个视图开始动画

这里的特殊性是我只使用两个视图,我想在这两个视图之间切换。

问题:

当我非常快速地多次点击按钮,然后停止点击时,两个视图同时显示在另一个上面,并且不会消失。容器仍然只包含一个视图......但绝对奇怪!

error screenshot http://i.minus.com/jDXyvUsE1LCOx.png

我能用一个简单的例子重现这个:

public class TestAnimActivity extends Activity implements OnClickListener {

private FrameLayout container;

private TextView current;
private TextView next;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    current = new TextView(this);
    current.setText("View 1 YEAH");
    next = new TextView(this);
    next.setText("       View 2 DOH");

    container = (FrameLayout) findViewById(R.id.container);
    container.addView(current);

    findViewById(R.id.button).setOnClickListener(this);
}

public void onClick(View v) {
    Animation outAnimation = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
    current.startAnimation(outAnimation);
    container.addView(next);
    container.removeView(current);

    TextView temp = current;
    current = next;
    next = temp;
}
}

正如您所看到的那样,动画正在视图中启动,而之前的动画仍然在运行,而我这样做的方式可能会成为问题的根源。

如果我评论动画相关的代码,它可以完美地运行:

// Animation outAnimation = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
// current.startAnimation(outAnimation);

如果我停止重复使用视图并创建新视图,它也可以完美运行:

// next = temp;
next = new TextView(this);
next.setText("View: " + new Random().nextInt());

但我不想创建新观点:-)。

似乎问题与在视图中添加/删除此视图时在视图上多次启动动画有关。

我首先尝试使用 ViewFlipper ,然后使用 ViewAnimator ,然后查找Android源代码并最终手动执行此操作以重现问题。

如果您希望布局能够自行测试,这是我的 main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Click me fast" />

</LinearLayout>

感谢您的时间!

2 个答案:

答案 0 :(得分:5)

我终于找到了解决问题的方法。

当我们从ViewGroup中删除视图时,如果此视图上正在运行动画,它将自动添加到ViewGroup的“消失的子项”列表中。

当我们尝试向ViewGroup添加一个已从其中删除但仍在其消失的子节点中的视图时,似乎出现了这个问题。

有一种简单的方法可以解决这个问题:viewGroup.clearDisappearingChildren();

以下是onClick()方法的新实现:

public void onClick(View v) {

    next.clearAnimation();
    container.clearDisappearingChildren();

    Animation outAnimation = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
    current.startAnimation(outAnimation);
    container.addView(next);
    container.removeView(current);

    TextView temp = current;
    current = next;
    next = temp;
}

答案 1 :(得分:0)

如果它在没有快速按下按钮的情况下工作,并且在没有动画的情况下工作,那么您可能会看到动画实际上是如何工作的。根据我的理解,动画中显示的内容与它们动画的View对象是分开的。您可以尝试从父视图设置动画,而不是继续添加和删除动画。或者确保在删除视图之前清理动画,因为它听起来像是视图无法获取onAnimationEnd方法,它可以删除正在显示的幻像(setFillAfter(false)这是动画的默认行为)。