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

Как начать анимацию сразу после onCreate?

Я следую http://developer.android.com/guide/topics/graphics/view-animation.html#frame-animation с незначительными изменениями. Я решил сделать цикл анимации и хочу, чтобы он начинался с get-go.

Моя анимация находится в drawable/listen.xml:

<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
    android:drawable="@drawable/l_01"
    android:duration="200" />
<item
    android:drawable="@drawable/l_02"
    android:duration="200" />
<item
    android:drawable="@drawable/l_03"
    android:duration="200" />
</animation-list>

и мой код инициализации:

 @Override public void onWindowFocusChanged(boolean hasFocus)  { 
      super.onWindowFocusChanged(hasFocus); 
      animImg = (ImageView)findViewById(R.id.listen_anim);
      animImg.setBackgroundResource(R.drawable.listening);
      anim = (AnimationDrawable) animImg.getBackground(); 
      anim.start();
 };

Все, что я вижу, это первый кадр и другие изображения.

4b9b3361

Ответ 1

Запустите это в onResume():

class AnimTask extends AsyncTask<String, String,String> {
            Activity act;
            AnimTask(Activity act) {
                this.act = act;
            }

            @Override
            protected String doInBackground(String... params) {
                act.runOnUiThread(new Runnable() {
                    public void run(){
                        animImg = (ImageView)findViewById(R.id.listen_anim);
                        animImg.setBackgroundResource(R.drawable.listening);
                        anim = (AnimationDrawable) animImg.getBackground();
                        anim.start();
                    }
                });
                return null;
            }
        }

Ответ 2

Это уже написано в учебнике:

Важно отметить, что метод start(), вызываемый в AnimationDrawable, не может быть вызван во время метода onCreate() вашей Activity, потому что AnimationDrawable еще не полностью привязан к окну.

Если вы хотите немедленно воспроизвести анимацию, не требуя взаимодействия, тогда вы можете вызвать ее из метода onWindowFocusChanged() в своей Activity, который вызывается, когда Android выводит ваше окно в фокус.

Поэтому переместите свой вызов, чтобы начать в одном из этих двух мест, в зависимости от вашего желания. На основе вашего комментария переместите свой вызов, чтобы начать с onWindowsFocusChanged().

ИЗМЕНИТЬ Итак, это "Как это сделать":

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    if(hasFocus){
        textView.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,
            android.R.anim.slide_in_left|android.R.anim.fade_in));
    }   
}

Обратите внимание на следующие пункты:

  • не забудьте написать случай if/else, чтобы проверить фокус
  • и удалите автоматически сгенерированный "super.onWindowFocusChanged(hasFocus);"

Ответ 3

Установите флаг в onAttachedToWindow(), а затем в onWindowFocusChanged() проверьте его и запустите анимацию.

@Override
void onWindowFocusChanged(boolean hasFocus) {
    if (hasFocus & mbFlag) {
        // start animation.
    }
}

Update

Просто расширьте класс ImageView и переопределите onFocusChange. Затем в вашей деятельности установите фокус на него, вызвав animImg.requestFocus(). Анимация должна начинаться, когда она фокусируется. Убедитесь, что ваше изображение настроено.
Если это не сработает, вы можете также переопределить метод onAttachedToWindow(). Установите флаг там и проверьте перед запуском анимации.

@Override
void onFocusChange(boolean hasFocus) {
    if (hasFocus) {
        // start animation.
    }
}

Ответ 4

Вы можете использовать метод post для любого View для активности. Вероятно, это должно выглядеть так:

View anyView = findViewById(R.id.anyView);
anyView.post(new Runnable()
{
    @Override
    public void run()
    {
        // Your code goes here
    }
});

Ответ 5

Вам нужно дать время менеджеру UI создавать соответствующие ресурсы ПЕРЕД началом анимации. Правильный шаблон

a) Create animation object in onCreate.
b) Start animation object elsewhere.

Не создавать и запускать в том же методе.

Ответ 6

Поскольку этот вопрос задавался давным-давно, я столкнулся с той же проблемой в 2019 году с использованием переходов Everywhere или AndroidX Transitions. И единственным решением для меня было использовать ответ @Muzikant. Просто позвоните в onCreate()

rootViewOfYourLayout.post {
            TransitionManager.beginDelayedTransition(rootViewOfYourLayout)
            someViewId.visibility = View.VISIBLE
        }

И это прекрасно работает, например, в моем случае для заставки.

Обновление
 Как после некоторого тестирования, кажется, что это решение имеет незначительную проблему. Анимация запускается, и вы блокируете телефон или перемещаете приложение в фоновый режим, и в результате, когда приложение снова на переднем плане, оно просто замирает, поскольку не получено никаких обратных вызовов TransitionListener, поэтому в моем случае onTransitionEnd() не вызывался, где была расположена логика, по которой пользователь мог перейти следующий экран.

На данный момент это работает для меня без проблем:

  override fun onWindowFocusChanged(hasFocus: Boolean) {
   if(hasFocus && isAnimationStarted.not()){
   rootViewOfYourLayout.post {
          TransitionManager.beginDelayedTransition(rootViewOfYourLayout)
          someViewId.visibility = View.VISIBLE
            }
  }
}

Ответ 7

animation = AnimationUtils.loadAnimation(this, R.anim.push_left_out);

yourobject.startanimation(animation);

Это может помочь