Подтвердить что ты не робот

Макетная анимация не работает при первом запуске

У меня есть Activity со списком элементов, и когда вы нажимаете на элемент, я хочу, чтобы элементы управления воспроизведением для этого элемента скользили со дна экрана и становились видимыми. Я определил набор анимаций для слайда и слайда, и они работают. Я настроил свой аниматор в моей деятельности и начал мой слайд в анимации onClick элемента. Моя проблема в том, что при первом запуске приложения, когда я нажимаю на элемент, выполняется обратный вызов onClick, но анимации не происходит. Второй раз, когда я нажимаю, происходит слайд в анимации, но не слайд. Третий и последующие времена, он работает так, как ожидалось. Вот мои анимационные наборы.

vm_slide_in.xml

    <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
           android:fillAfter="true">
    <translate
        android:fromYDelta="800"
        android:toYDelta="0"
        android:duration="600" />
</set>

vm_slide_out.xml

    <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
           android:fillAfter="true">
    <translate
        android:fromYDelta="0"
        android:toYDelta="800"
        android:duration="600" />
</set>

Вот мой макет активности

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/AppBG">
    <RelativeLayout 
        style="@style/LogoBar" 
        android:id="@+id/logo_bar"      
        android:layout_alignParentTop="true">
        <include layout="@layout/logobar"></include>
    </RelativeLayout>
    <RelativeLayout 
        style="@style/TitleBar" 
        android:id="@+id/title_bar"     
        android:layout_below="@+id/logo_bar">
        <include layout="@layout/titlebar"></include>"
        <Button style="@style/TitleBarButton"
            android:id="@+id/vm_speaker_btn"
            android:text="@string/vm_speaker_btn_label" 
            android:layout_alignParentLeft="true"
            android:layout_margin="4dp">
        </Button>
        <Button style="@style/TitleBarButton"
            android:id="@+id/vm_edit_btn"
            android:text="@string/vm_edit_btn_label" 
            android:layout_alignParentRight="true"
            android:layout_margin="4dp">
        </Button>
    </RelativeLayout>
    <ListView
        android:id="@+id/@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title_bar"/>
    <RelativeLayout
        android:id="@+id/vm_control_panel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/footer"
        android:visibility="gone">
        <include layout="@layout/vm_control"/>
    </RelativeLayout>
    <RelativeLayout
        android:id="@+id/footer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">
        <include layout="@layout/taskbar"/>
    </RelativeLayout>
</RelativeLayout>

Вот макет для включенного элемента управления

    <?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout 
        android:id="@+id/vm_control"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/dark_grey">
        <TextView
            android:id="@+id/vm_ctl_branding"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dp"
            android:text="@string/branding"
            android:textColor="@color/white">
        </TextView>
        <TextView style="@style/TimeMark"
            android:id="@+id/vm_timestamp"
            android:layout_toLeftOf="@+id/vm_progress"
            android:layout_below="@+id/vm_ctl_branding"
            android:layout_marginRight="3dp"
            android:text="0:00">
        </TextView>
        <SeekBar
            android:id="@+id/vm_progress"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/vm_ctl_branding"
            android:layout_centerHorizontal="true">
        </SeekBar>
        <TextView style="@style/TimeMark"
            android:id="@+id/vm_timeleft"
            android:layout_toRightOf="@+id/vm_progress"
            android:layout_below="@+id/vm_ctl_branding"
            android:layout_marginLeft="3dp"
            android:text="-0:00">
        </TextView>
        <LinearLayout
            android:id="@+id/vm_action_button_layout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/vm_timestamp"
            android:layout_alignRight="@+id/vm_timeleft"
            android:orientation="horizontal"
            android:layout_below="@+id/vm_progress">
            <TextView style="@style/Vm_Action_Button"
                android:background="@drawable/vm_action_btn_call"
                android:id="@+id/vm_callback_btn"
                android:layout_marginRight="5dp"
                android:text="@string/vm_action_btn_callback">
            </TextView>
            <TextView style="@style/Vm_Action_Button"
                android:background="@drawable/vm_action_btn_delete"
                android:id="@+id/vm_delete_btn"
                android:layout_marginLeft="5dp"
                android:text="@string/vm_action_btn_delete">
            </TextView>
        </LinearLayout>
    </RelativeLayout>
</merge>

Из моего метода onCreate...

// Handle list item selections
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final Voicemail vmItem = (Voicemail) vmla.getItem(position);
        Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT)
                .show();
        vVm_controls.startAnimation(mSlideIn);
    }
});

И мои обратные вызовы анимации...

@Override
public void onAnimationStart(Animation animation) {
    vm_controls_in = !vm_controls_in;
    if (vm_controls_in) {
        vVm_controls.setVisibility(View.GONE);
    } else {
        vVm_controls.setVisibility(View.VISIBLE);
        // vVm_controls.bringToFront();
    }
}

@Override
public void onAnimationEnd(Animation animation) {
    if (!vm_controls_in) {
        try {
            Thread.sleep(1000);
            vVm_controls.startAnimation(mSlideOut);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

@Override
public void onAnimationRepeat(Animation animation) {
    // TODO Auto-generated method stub

}
4b9b3361

Ответ 1

Как вы обнаружили, проблема - видимость. Когда представление первоначально установлено как ушедшее в xml файл, Android не будет отображать макет до тех пор, пока видимость не будет изменена на видимую или невидимую. Если вы попытаетесь анимировать изображение, которое еще не было отображено, анимация будет отображаться в представлении без макета. После того, как анимация завершится, она отобразит ее, и внезапно представление появится без анимации. Он работает в последующие моменты времени, потому что представление имеет макет, даже когда он установлен.

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

Ответ 2

Конечно, через 20 минут после публикации этого вопроса я выяснил свою проблему. Поскольку я настраивал видимость моего макета на "GONE", когда я пытался запустить анимацию, он не запускался в первый раз. Не уверен, почему он идет 2-й и последующие времена, но если я установил видимость "VISIBLE" прямо перед началом анимации, она устранила проблему. Вот код, в котором я его изменил...

// Handle list item selections
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final Voicemail vmItem = (Voicemail) vmla.getItem(position);
        Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT)
                .show();
        vVm_controls.setVisibility(View.VISIBLE);
        vVm_controls.startAnimation(mSlideIn);
    }
});

Ответ 3

Я не знаю, все ли в курсе, но да, это проблема с видимостью. Поэтому я устанавливаю видимость в файле xml невидимым и вызывается в том месте, где инициализируется ваше представление:

view.post(new Runnable() {
    @Override
    public void run() {
        view.animate().translationY(view.getHeight());
    }
};

Теперь вызов

view.animate().translationY(0).setListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationStart(Animator animation) {
        super.onAnimationStart(animation);
        view.setVisibility(View.VISIBLE);
    }
}

работает также в первый раз.

Ответ 4

Была такая же проблема, даже если я настраивал представление на вид в начале анимации. Я следил за советом brockoli и задавал его видимость перед началом анимации, и это работало как шарм.

ДО:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left);
animation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        view.setVisibility(View.VISIBLE);
    }

    @Override
    public void onAnimationEnd(Animation animation) { }

    @Override
    public void onAnimationRepeat(Animation animation) {       }
);
view.startAnimation(animation);

ПОСЛЕ:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left);
view.setVisibility(View.VISIBLE);
view.startAnimation(animation);

Ответ 5

Если проблема связана с видимостью, вам нужно только отложить анимацию после рендеринга, например:

vVm_controls.setVisibility(View.INVISIBLE);
vVm_controls.post(() -> vVm_controls.startAnimation(mSlideIn));

Ответ 6

У меня была аналогичная проблема в Android 4.4.3. Я попробовал большинство предложенных решений, но только одно решение отлично работало для меня. Вы должны запустить анимацию после завершения рендеринга окна, и лучший способ - запустить его внутри onWindowFocusChanged. Не используйте задержку через runnable, так как это повлияет на производительность вашего приложения в высокоскоростных мобильных телефонах.

@Override
public void onWindowFocusChanged (boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   if (hasFocus)
      yourView.startAnimation(anim);
}

дополнительную информацию можно найти в этом сообщении: https://damianflannery.wordpress.com/2011/06/08/start-animation-in-oncreate-or-onresume-on-android/

Ответ 7

У меня была такая же проблема, но с помощью ViewPropertyAnimator. Например, вы объявляете GridView, называемый mGridView. Все, что вам нужно сделать, это вызвать mGridView.animate() с желаемыми изменениями.

Анимация моего GridView была запущена, но из-за неизвестных обстоятельств не было видимой видимой анимации. Я также изменил все View.GONE на View.VISIBLE, но ничего не изменил. В моем случае я понял, что мне просто пришлось удалить android:requiresFadingEdge="vertical" в свой XML этого конкретного GridView. Возможно, невозможно использовать Fading Edge в комбинации с ViewPropertyAnimator.

Ответ 8

Я знаю, что этот вопрос старый, но мой ответ может помочь другим. Когда нам нужно анимировать вид, но по умолчанию его видимость исчезла тогда, пожалуйста, установите все свойства скрыть код в XML Для моего случая я использовал перевод Y и альфа в Java файле. Я сделал простые вещи, чтобы решить проблему при первом запуске. Затем добавлены все атрибуты в XML, которые используются в коде.