首页 > 技术文章 > Android 动画效果

huanyi0723 2016-01-11 19:37 原文

动画效果

public class AnimationTestActivity extends Activity {
    private final String TAG = "xmp";
    private Button alphaBtn;
    private Button transBtn;
    private Button scaleBtn;
    private Button rotateBtn;
    private Button scaleRotateBtn;
    private Button frameBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initControls();
    }

    private void initControls() {
        alphaBtn = (Button) findViewById(R.id.alpha);
        transBtn = (Button) findViewById(R.id.translate);
        scaleBtn = (Button) findViewById(R.id.scale);
        rotateBtn = (Button) findViewById(R.id.rotate);
        scaleRotateBtn = (Button)findViewById(R.id.scale_rotate);
        frameBtn = (Button) findViewById(R.id.frame);
        
        alphaBtn.setOnClickListener(new BtnOnClickListener());
        transBtn.setOnClickListener(new BtnOnClickListener());
        scaleBtn.setOnClickListener(new BtnOnClickListener());
        rotateBtn.setOnClickListener(new BtnOnClickListener());
        scaleRotateBtn.setOnClickListener(new BtnOnClickListener());
        frameBtn.setOnClickListener(new BtnOnClickListener());
    }

    class BtnOnClickListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            Log.v(TAG,"--------------->onClick");
            switch (v.getId()) {
                case R.id.alpha:
                    testAlphaEffect();
                    break;
                case R.id.translate:
                    testTransEffect();
                    break;
                case R.id.scale:
                    testScaleEffect();
                    break;
                case R.id.rotate:
                    testRotateEffect();
                    break;
                case R.id.scale_rotate:
                    testScaleRotateEffect();
                    break;
                case R.id.frame:
                    testFrameEffect();
                    break;
                default:
                    break;
            }
        }
    }

    private void testAlphaEffect() {
        Intent intent = new Intent("anim.test");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.putExtra(TestEffectActivity.TYPE, TestEffectActivity.EFFECT_ALPHA);
        startActivity(intent);
        Log.v(TAG,"--------->testAlphaEffect");
    }
    private void testTransEffect() {
        Intent intent = new Intent("anim.test");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.putExtra(TestEffectActivity.TYPE, TestEffectActivity.EFFECT_TRANS);
        startActivity(intent);
        Log.v(TAG,"--------->testTransEffect");
    }
    private void testScaleEffect() {
        Intent intent = new Intent("anim.test");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.putExtra(TestEffectActivity.TYPE, TestEffectActivity.EFFECT_SCALE);
        startActivity(intent);
        Log.v(TAG,"--------->testTransEffect");
    }
    private void testRotateEffect() {
        Intent intent = new Intent("anim.test");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.putExtra(TestEffectActivity.TYPE, TestEffectActivity.EFFECT_ROTATE);
        startActivity(intent);
        Log.v(TAG,"--------->testTransEffect");
    }
    private void testScaleRotateEffect(){
        Intent intent = new Intent("anim.test");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.putExtra(TestEffectActivity.TYPE, TestEffectActivity.EFFECT_SCALE_ROTATE);
        startActivity(intent);
        Log.v(TAG,"--------->testTransEffect");
    }
    private void testFrameEffect(){
        Intent intent = new Intent("anim.test");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.putExtra(TestEffectActivity.TYPE, TestEffectActivity.EFFECT_FRAME);
        startActivity(intent);
        Log.v(TAG,"--------->testFrameEffect");
    }
}
public class TestEffectActivity extends Activity {
    private final String TAG = "xmp";
    private Context mContext;
    private View effectView ;
    private TextView textWidget;
    public final static String TYPE = "type";
    public final static int EFFECT_ALPHA = 1;
    public final static int EFFECT_TRANS = 2;
    public final static int EFFECT_SCALE = 3;
    public final static int EFFECT_ROTATE = 4;
    public final static int EFFECT_SCALE_ROTATE = 5;
    public final static int EFFECT_FRAME = 6;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_effect);
        mContext = this;
    }
    @Override
    protected void onStart() {
        super.onStart();
        handleEffect();
    }

    private void handleEffect() {
        Intent intent = getIntent();
        int effectType = intent.getIntExtra(TYPE, 0);
        switch (effectType) {
        case EFFECT_ALPHA:
            handleAlphaEffect();
            break;
        case EFFECT_TRANS:
            handleTransEffect();
            break;
        case EFFECT_SCALE:
            handleScaleEffect();
            break;
        case EFFECT_ROTATE:
            handleRotateEffect();
            break;
        case EFFECT_SCALE_ROTATE:
            handleScaleRotateEffect();
            break;
        case EFFECT_FRAME:
            handleFrameEffect();
            break;
        default:
            break;
        }
    }
    private void exit(){
        finish();
    }
    
    /*
     * 监听是否播放状态
     */
    class EffectAnimationListener implements AnimationListener{
        @Override
        public void onAnimationEnd(Animation animation) {
            exit();
        }
        @Override
        public void onAnimationRepeat(Animation animation) {}
        @Override
        public void onAnimationStart(Animation animation) {}
    }
    private void handleAlphaEffect() {
        Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.alpha);
        anim.setAnimationListener(new EffectAnimationListener());
        textWidget = (TextView)findViewById(R.id.text_widget);
        textWidget.setText(" 渐变透明度动画效果");
        textWidget.startAnimation(anim);
        Log.v(TAG,"--------------->handleAlphaEffect");
    }

    private void handleTransEffect() {
        Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.trans);
        anim.setAnimationListener(new EffectAnimationListener());
        textWidget = (TextView)findViewById(R.id.text_widget);
        textWidget.setText(" 转换位置移动动画效果");
        textWidget.startAnimation(anim);
        Log.v(TAG,"--------------->handleTransEffect");
    }

    private void handleScaleEffect() {
        Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.scale);
        anim.setAnimationListener(new EffectAnimationListener());
        textWidget = (TextView)findViewById(R.id.text_widget);
        textWidget.setText(" 渐变尺寸伸缩动画效果");
        textWidget.startAnimation(anim);
        Log.v(TAG,"--------------->handleTransEffect");
    }

    private void handleRotateEffect() {
        Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.rotate);
        anim.setAnimationListener(new EffectAnimationListener());
        textWidget = (TextView)findViewById(R.id.text_widget);
        textWidget.setText(" 画面转移旋转动画效果");
        textWidget.startAnimation(anim);
        Log.v(TAG,"--------------->handleRotateEffect");
    }
    private void handleScaleRotateEffect(){
        Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.scale_rotate);
        anim.setAnimationListener(new EffectAnimationListener());
        textWidget = (TextView)findViewById(R.id.text_widget);
        textWidget.setText(" 画面缩放旋转动画效果");
        textWidget.startAnimation(anim);
        Log.v(TAG,"--------------->handleRotateEffect");
    }
    
    /*
     * 监听是否播放状态
     */
    class FrameAnimationListener implements AnimationDrawableListener{
        @Override
        public void onAnimationEnd(AnimationDrawable animation) {
            exit();
        }
        @Override
        public void onAnimationStart(AnimationDrawable animation) {
            
        }
    }
    private void handleFrameEffect() {
        AnimationDrawable anim = (AnimationDrawable)getResources().
                getDrawable(R.drawable.frame);
        CustomAnimDrawable cusAnim = new CustomAnimDrawable(anim);
        cusAnim.setAnimationListener(new FrameAnimationListener());
        textWidget = (TextView)findViewById(R.id.text_widget);
        textWidget.setText(" 画面逐帧动画效果");
        textWidget.setBackgroundDrawable(anim);
        cusAnim.start();
        Log.v(TAG,"--------------->handleFrameEffect");
    }
}
public class CustomAnimDrawable extends AnimationDrawable {
    private final String TAG = "xmp";
    private AnimationDrawable mOriAnim;
    private AnimationDrawable mSelf;
    private Handler mHandler;
    private boolean mStarted;
    private AnimEndListenerRunnable mEndRunnable;
    private AnimationDrawableListener mListener;

    public CustomAnimDrawable(AnimationDrawable anim) {
        mOriAnim = anim;
        initialize();
    }

    private void initialize() {
        mSelf = this;
        mStarted = false;
        mHandler = new Handler();
        mEndRunnable = new AnimEndListenerRunnable();
        for (int i = 0; i < mOriAnim.getNumberOfFrames(); i++) {
            mSelf.addFrame(mOriAnim.getFrame(i), mOriAnim.getDuration(i));
        }
    }

    @Override
    public void start() {
        mOriAnim.start();
        mStarted = true;
        mHandler.post(mEndRunnable);
        if (mListener != null) {
            mListener.onAnimationStart(mSelf);
        }
        Log.v(TAG, "------CustomAnimDrawable------>start");
    }
    
    /**
     * 循环检测 动画的状态
     */
    class AnimEndListenerRunnable implements Runnable {
        @Override
        public void run() {
            // 动画已开始
            if (!mStarted) {
                return;
            }
            // 未停止继续监听
            if (!isEnd()) {
                //这里的延迟时间是跟你的每一帧动画时间有关,基本保持一致就可以,最后一帧也会完整播放
                //上面动画时间为每一帧1000ms,所以这里设为了1000ms
                mHandler.postDelayed(mEndRunnable,1000);
                return;
            }
            Log.v(TAG, "----------->over");
            // 动画已结束
            if (mListener != null) {
                mStarted = false;
                mListener.onAnimationEnd(mSelf);
            }
        }
    }
    /**
     * 判断动画是否结束 采用反射机制
     * @return
     */
    private boolean isEnd(){
        Class<AnimationDrawable> animClass = AnimationDrawable.class;
        try{  
            //利用Java反射方法判断是否结束
            //获得私有方法  例如
            //Method method = animClass.getDeclaredMethod("nextFrame",boolean.class);
            
            //访问其私有变量
            Field field = animClass.getDeclaredField("mCurFrame");
            field.setAccessible(true);
            
            int currFrameNum = field.getInt(mOriAnim);
            int totalFrameNum = mOriAnim.getNumberOfFrames();
            if((currFrameNum == totalFrameNum - 1)||
               (currFrameNum == -1)){
                return true;
            }
        }
        catch (Exception e) {
            Log.v(TAG,"-------->Exception");
        }
        
        return false;
    }

    public void setAnimationListener(AnimationDrawableListener listener) {
        mListener = listener;
    }
    
    public interface AnimationDrawableListener {
        /**
         * Notifies the start of the animation
         * @param animation
         */
        public void onAnimationStart(AnimationDrawable animation);
        /**
         * Notifies the end of the animation
         * @param animation
         */
        public void onAnimationEnd(AnimationDrawable animation);
    }
}

Code见 https://github.com/huanyi0723/animationTest/

推荐阅读