Быстрое переключение и анимация представлений в FrameLayout портит представления - PullRequest
2 голосов
/ 28 декабря 2011

У меня очень странная проблема с анимацией Android, я пробовал много разных подходов и компонентов, и все еще не мог найти никакого объяснения.

У меня есть FrameLayout , который является контейнеромдля представлений и Кнопка .

Этот FrameLayout должен отображать только одно представление за один раз, и когда я нажимаю на Кнопка , я хочу, чтобы FrameLayout отображал другое представление , и запускает анимацию в представлении , которое удаляется из FrameLayout.

Специфика здесь в том, что я использую только два вида , и я хочу переключаться между этими двумя видами.

Проблема:

Когда я нажимаю кнопкуНесколько раз действительно быстро, а затем перестать щелкать, два вида отображаются одновременно один поверх другого, и не исчезают.Контейнер все еще содержит только одно представление, хотя ... определенно странно!

снимок экрана ошибки 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 и в итоге сделал это вручную, чтобы воспроизвести проблему.

Если вы хотите, чтобы макет можно было протестировать самостоятельно, вотmy 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 ]

5 голосов
/ 29 января 2012

Я наконец нашел способ исправить проблему.

Когда мы удаляем представление из 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;
}
0 голосов
/ 10 января 2012

Если он работает без быстрого нажатия кнопки и работает без анимации, вы можете увидеть, как на самом деле работают анимации. Насколько я понимаю, то, что отображается в анимации, отделено от объектов, которые они анимируют. Вы можете попробовать анимировать из родительского представления вместо тех, которые продолжают добавляться и удаляться. Или обязательно очистите анимацию перед удалением представления, так как это звучит так, как будто представление не может получить метод onAnimationEnd, где он может удалить отображаемое фантомное изображение (setFillAfter (false), которое является поведением анимации по умолчанию ).

...