Применение трансформации после анимации объекта на Android - PullRequest
3 голосов
/ 09 ноября 2010

Я пытаюсь анимировать изображение шара, поступающее на экран, смещая положение на экране и возвращаясь из экрана.Я хочу сделать это в виде 3 анимаций;ball_in, ball_shift и ball_out, а также возможность решать, когда переходить от одной анимации к другой.

Это код, который я получил до сих пор;

Main.xml

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

<ImageView android:id="@+id/ballImage" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" 
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_margin="5px"
android:src="@drawable/red_ball"
/>


</RelativeLayout>

Основная деятельность

public class AnimationTest extends Activity
{
    AnimationDrawable ballAnimation;

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

      final ImageView ballImage = (ImageView) findViewById(R.id.ballImage);

      final Animation ballOutAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_out);

      final Animation ballShiftAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_shift);
      ballShiftAnimation.setAnimationListener( new AnimationListener()
        {

            @Override
            public void onAnimationEnd(
                    Animation animation) {

                ballImage.startAnimation(ballOutAnimation);
            }

            @Override
            public void onAnimationRepeat(
                    Animation animation) {}

            @Override
            public void onAnimationStart(
                    Animation animation) {}

        });

      final Animation ballInAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_in);
      ballInAnimation.setAnimationListener( new AnimationListener()
        {

            @Override
            public void onAnimationEnd(
                    Animation animation) {
                ballImage.startAnimation(ballShiftAnimation);
            }

            @Override
            public void onAnimationRepeat(
                    Animation animation) {}

            @Override
            public void onAnimationStart(
                    Animation animation) {}

        });

      ballImage.startAnimation(ballInAnimation);

    }

}

ball_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
    android:fromXDelta="150"
    android:toXDelta="0"

    android:fromYDelta="0"
    android:toYDelta="0"

    android:duration="2000"
    android:startOffset="0"
    />

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">        
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"

        android:fromYDelta="-150"
        android:toYDelta="0"

        android:duration="1500"
        android:startOffset="500"
        />

</set>

</set>

ball_shift.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
    android:fromXDelta="0"
    android:toXDelta="130"

    android:fromYDelta="0"
    android:toYDelta="220"

    android:duration="2000"
    android:startOffset="0"

    android:fillAfter="true"
    />

<scale
    android:fromXScale="1.0" 
    android:toXScale="0.623"

    android:fromYScale="1.0" 
    android:toYScale="0.623" 

    android:duration="2000"
    android:startOffset="0"

    android:fillAfter="true"
    />

</set>

ball_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">        
<scale
    android:fromXScale="0.623" 
    android:toXScale="0.623"

    android:fromYScale="0.623" 
    android:toYScale="0.623" 
    />

<translate
    android:fromXDelta="130"
    android:toXDelta="330"

    android:duration="2000"
    android:startOffset="0"
    />
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">        
    <translate
        android:fromYDelta="220"
        android:toYDelta="370"

        android:duration="1900"
        android:startOffset="100"
        />

</set>

</set>

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

Я попытался использовать fillAfter / fillBefore,который описывается как применение преобразований после / до процесса анимации, но, похоже, они ничего не делают с изображением.Он все еще возвращается в исходное положение.

Любая помощь или предложения о том, как это сделать, приветствуются.Спасибо.

Ответы [ 3 ]

3 голосов
/ 06 июня 2012

Вы должны использовать AnimationSet для программной конкатенации анимации в Android. Это должно выглядеть примерно так

AnimationSet anim = new AnimationSet(false);

final Animation ballInAnimation = AnimationUtils.loadAnimation(this,
            R.anim.ball_in);
ballInAnimation.setFillBefore(true);

final Animation ballShiftAnimation = AnimationUtils.loadAnimation(this,R.anim.ball_shift);
ballShiftAnimation.setStartOffset(ballInAnimation.getDuration());

final Animation ballOutAnimation = AnimationUtils.loadAnimation(this,R.anim.ball_out);
ballOutAnimation.setStartOffset(ballInAnimation.getDuration()+ ballShiftAnimation.getDuration());

anim.addAnimation(ballInAnimation);
anim.addAnimation(ballShiftAnimation);
anim.addAnimation(ballOutAnimation);
anim.setFillAfter(true);

ballImage.startAnimation(anim);

Это должно работать, если ваши TweenAnimations, определенные в XML, правильно подключены. Обратите внимание, что это будет работать только ВИЗУАЛЬНО, если вам нужно, чтобы представление было кликабельным, вы должны использовать ValueAnimator вместо анимации

1 голос
/ 03 сентября 2012

Хаки, но вы можете получить окончательное преобразование и применить его к вашему ImageView. Я не проверял на самом деле применение возвращенной матрицы, но код отражения работает хорошо.

@Override
public void onAnimationEnd(Animation animation) {
            Transformation t = new Transformation();
            final float interpolatedTime = animation.getInterpolator().getInterpolation(animation.getDuration());
            Class params[] = {Float.TYPE, Transformation.class};
            try {

                Method m = mAnimationYouWantToGetFinalTransformationFrom.getClass().getDeclaredMethod("applyTransformation", params);
                m.setAccessible(true);
                m.invoke(mAnimationYouWantToGetFinalTransformationFrom, interpolatedTime, t);

                // update object to this final transformation matrix
                // For Example: mObjectMatrix = t.getMatrix();

                // run your next animation
            }  // Necessary Catch blocks

Этой проблемы можно избежать для проектов, использующих 3.0 и более поздние версии. Используйте ValueAnimator - анимация обновляет свойства реального объекта (в данном случае, вашего ballImage) вместо анимации представления вашего объекта (как это делают «старые» анимации Translate и Scale).

0 голосов
/ 09 ноября 2010

Возможно, это не самое элегантное решение, и оно может не сработать, но его стоит попробовать.

Перед вызовом следующей анимации в методе onAnimationEnd() попытайтесь установить новую позицию ImageViews в позицию, в которой анимация закончилась, используя метод setFrame () . Это может не сработать, так как я сам не проверял, но попробуй и скажи мне результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...