Получение матрицы преобразования анимации в Android - PullRequest
2 голосов
/ 02 апреля 2010

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

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

Однако, если я использую getTransformation перед запуском анимации, я получаю единичную матрицу. И если я использую это так:

public void onAnimationEnd(Animation animation) {
    Transformation t = new Transformation();
    animation.getTransformation(animation.getDuration(), t);
}

Программа входит в бесконечный цикл, потому что getTransformation, кажется, вызывает onAnimationEnd (почему?).

Как мне использовать getTransformation для получения матрицы преобразования анимации? Есть ли другой способ сделать это?

Ответы [ 2 ]

0 голосов
/ 06 марта 2013

Я также столкнулся с этой проблемой, когда я хочу получить getTransformation () для следующей анимации после предыдущей анимации, а затем бесконечный цикл вызывает переполнение стека.

Я проанализировал проблему с исходным кодом Android из GrepCode , с кодами ниже в getTransformation(), я никогда не нахожу никаких проблем, которые вызовут бесконечный цикл, так как только при вызове onAnimationEnd() он установит mEnded до истины. В следующий раз позвоните getTransformation(), он должен быть заблокирован if(!mEnded), но это не так.

    if (expired) {
        if (mRepeatCount == mRepeated) {
            if (!mEnded) {
                mEnded = true;   //this is not real!!!
                if (mListener != null) {
                    mListener.onAnimationEnd(this);
                }
            }
        } else {
            if (mRepeatCount > 0) {
                mRepeated++;
            }

            if (mRepeatMode == REVERSE) {
                mCycleFlip = !mCycleFlip;
            }

            mStartTime = -1;
            mMore = true;

            if (mListener != null) {
                mListener.onAnimationRepeat(this);
            }
        }
    }

В этом сегменте кода grepcode неверен. Правда в том, что eEnded = true устанавливается после onAnimationEnd(), называемого:

    if (!mEnded) {
            if (mListener != null) {
                mListener.onAnimationEnd(this);
            }
            //it happen after onAnimationEnd(). cancel() is also does as this
            mEnded = true; 
        }

Это должно объяснить, почему происходит бесконечный цикл. Даже если вы проверите animation.hasEnded(), это не поможет, так как не удалось установить для mEnded значение true.

Способы решения этой проблемы:
Установить флаг в слушателе для охраны:

boolean needBlock = false;
public void onAnimationEnd(Animation animation)
{
   if ( needBlock ) return;

   needBlock = true;
   Transformation t= new Transformation();
   animation.getTransformation(animation.getDuration(), t);
}

Очистить AnimationListner. При необходимости мы можем вернуться после

public void onAnimationEnd(Animation animation)
{
   animation.setAnimationListener(null);
   Transformation t= new Transformation();
   animation.getTransformation(animation.getDuration(), t);
   animation.setAnimationListener(this);
}
0 голосов
/ 17 августа 2010

Потому что по какой-то причине именно так кодируется getTransformation.

http://www.netmite.com/android/mydroid/1.5/frameworks/base/core/java/android/view/animation/Animation.java

Похоже, вы можете проверить hasEnded (), чтобы увидеть, завершена ли анимация. Попробуйте что-то вроде этого:

public void onAnimationEnd(Animation animation)
{
   if ( animation.hasEnded() )
       return;

   Transformation t= new Transformation();
   animation.getTransformation(animation.getDuration(), t);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...