Android动画:同步vs顺序



我使用两个图像(img_heart_1img_heart_2)。我有两个动画,一个是翻译的,另一个是缩放的text_anim.xml: animi(Animation), bounce_up.xml :bounce_up_anim(Animation)

  • 顺序:一个动画接一个动画。
  • simultaneous:同时显示两个图像动画

  • 独占:两个动画(每个图像一个)

  • 包括:只有一个动画(AnimationUtils.loadAnimation(this, R.anim.Same))用于两个图像动画。

结果是顺序和不同的动画,预期的结果。但如果我从firstAnimationAsync中剪切secAnim.execute();并放入onResume,两个动画将同时运行,只有一次

如果我保持secAnim.execute()onResume(),并把img_heart_2.startAnimation(animi);而不是img_heart_2.startAnimation(bounce_up_anim);,它将运行一次,同时。

如果我把secAnim.execute()放在firstAnimationAsynconPostExecute()中,并为两个图像保留startAnimation(animi),现在,第一个动画将第一次运行,然后第二次两个动画将运行。

为什么会这样?

同样,如果两个图像同时出现,第二个图像看起来有点受压(垂直向下压缩)。我也把da=null,(现在评论)它不应该无效的动画?

我还希望我的翻译动画坚持到结束,而不是弹回或变得不可见。

代码: text_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false"
    >
        <translate
            android:fromXDelta="0"
            android:toXDelta="50"
            android:fromYDelta="0"
            android:toYDelta="100"
            android:duration="3000"
            android:fillAfter="false"/>

</set>

code: bounce_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
        <scale 
            android:fromXScale="1.0"
            android:toXScale="2.0"
            android:fromYScale="1.0"
            android:toYScale="3.0"
            android:pivotX="50%"
            android:pivotY="0%"
            android:duration="3000"/>   
</set>
代码:anidro.java
package my.trials.anidro;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class anidro extends Activity {
    ImageView img_heart_1,img_heart_2, img_heart_3;
    Animation animi, bounce_up_anim;
    Bitmap b1,b2;
    firstAnimationAsync da;
    secondAnimAsync secAnim;
    @Override
    public void onPause(){
        super.onPause();
    }
    @Override
    public void onResume(){
        super.onResume();
        InitializeLayouts();
        **da.execute();**
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    private void InitializeLayouts() {  
        img_heart_1=(ImageView)findViewById(R.id.lay_main_heartImg);
        img_heart_2 = (ImageView)findViewById(R.id.lay_main_heart2Img);
        **bounce_up_anim**=AnimationUtils.loadAnimation(this, R.anim.bounce_up);
        **animi** = AnimationUtils.loadAnimation(this, R.anim.text_anim);
        b1 = BitmapFactory.decodeResource(getResources(),R.drawable.anidro_heart2); 
        b2=BitmapFactory.decodeResource(getResources(), R.drawable.anidro_heart3);
        da= new firstAnimationAsync();
        secAnim = new secondAnimAsync();
        //img_heart_12=(ImageView)findViewById(R.id.lay_main_koalaImg);
    }
    private class firstAnimationAsync extends AsyncTask<Void, Void, Void>{
        protected void onPreExecute(){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            img_heart_1.setImageBitmap(b1);
            img_heart_1.setVisibility(View.VISIBLE);
            img_heart_1.startAnimation(**animi**);
            //img_heart_1.setVisibility(View.INVISIBLE);
        }
        @Override
        protected Void doInBackground(Void...params){
            try{
                Thread.sleep(1800);
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            return null;
        }
        protected void onPostExecute(Void v){
                    **secAnim.execute();**
            //da=null;
            return;
        }
    }
    private class secondAnimAsync extends AsyncTask<Void, Void, Void>{
        protected void onPreExecute(){
            img_heart_2.setImageBitmap(b2);
            //da=null;
            img_heart_2.setVisibility(View.VISIBLE);
            //img_heart_1.setVisibility(View.INVISIBLE);
            img_heart_2.startAnimation(**bounce_up_anim**);
        }
        protected Void doInBackground(Void...params){
            try{
                Thread.sleep(5000);
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
            return null;
        }
        protected void onPostExecute(Void v){
            //secAnim = null;
            return;
        }
    }
}

我知道这是一个老问题,但为了将来的参考,您可以使用AnimationSet。Builder

Builder对象是一个实用程序类,用于方便地向AnimatorSet添加动画以及各种动画之间的关系。Builder方法以及AnimatorSet的play()方法的目的是使以一种自然的方式表达动画的依赖关系成为可能。如果需要的话,开发者也可以使用playTogether()和playsequential()方法,但在某些情况下,成对地表达动画的AnimatorSet可能更容易。

例如,这将设置一个AnimatorSet同时播放anim1和anim2, anim3在anim2完成时播放,anim4在anim3完成时播放:

AnimatorSet s = new AnimatorSet();
s.play(anim1).with(anim2);
s.play(anim2).before(anim3);
s.play(anim4).after(anim3);

你真的不应该用ASyncTask处理图形化的东西。没有人能准确地预测系统中任务将在什么时候执行,所以这是一个非常糟糕的主意。

为什么不使用动画监听器呢?你只需要创建你的第一个动画,并添加一个新的动画监听器,它将在第一个动画的开始或结束时启动你的第二个动画。

对于null动画,只需调用

img_heart.clearAnimation();

对于操纵杆结束,我不确定你想要什么,但可能你想让你的图像在动画结束时停留在它的位置,所以,你需要在动画声明中设置这个属性:

android:fillAfter="true"
android:fillBefore="false"
android:fillEnabled="true"

Only fillAfter似乎是强制性的,所以先尝试它,但如果它不起作用,添加接下来的两行。

最新更新