Android之开门动画的实现

实现原理

  • 如何将一个View视图一分为二?(效果图:)
Android之开门动画的实现_第1张图片
OpenAnim.gif

实现步骤

  1. 其实就是将整个View视图缓存成一张图片,需要开启一下功能

     //缓存图像
            mMainContainer.setDrawingCacheEnabled(true);  //开启缓存
            mMainContainer.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); //设置缓存的质量
             Bitmap bitmap = mMainContainer.getDrawingCache();
    
  • 注意事项:

    1. 如果以上方法放在Activity的onCreate(),onStart(),onResume()方法调用.那么getDrawingCache()方法会返回一个Null,那么就会空指针异常,原因:

      1. 因为在onCreate(),onStart(),onResume方法中,View还没有测量完成,布局完成,所以拿不到宽高,只有0,所以这个时候getDrawingCache()方法就会返回Null.我画了个图:如图所示:
Android之开门动画的实现_第2张图片
View框架视图.png
  1. 解决方法:(解决方法很多)

    • 可以在onResume()方法中开辟线程,并延时300ms执行以上方法.这个时候子View就被添加到了DectorView中了

    • 我是在onWindowFocusChanged方法中调用.在这个方法中子View已经添加到DectorView中了,所以已经有宽高属性了

       @Override
          public void onWindowFocusChanged(boolean hasFocus) {
              super.onWindowFocusChanged(hasFocus);
              initData();
          }
      

      initData()方法:

        //缓存图像
              mMainContainer.setDrawingCacheEnabled(true);  //开启缓存
              mMainContainer.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); //设置缓存的质量
               Bitmap bitmap = mMainContainer.getDrawingCache();
      
    • 或者手动进行测量,布局.添加如下代码:

       mMainContainer.setDrawingCacheEnabled(true);  //开启缓存
              mMainContainer.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); //设置缓存的质量
              mMainContainer.buildDrawingCache();
              mMainContainer.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                      View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
              mMainContainer.layout(0, 0, mMainContainer.getMeasuredWidth(), mMainContainer.getMeasuredHeight());
              Bitmap bitmap = mMainContainer.getDrawingCache();
      

  2. 缓存好View视图为图片之后,就需要将这张图片一份为2了,那么就需要两个容器装着左半部分图片和右半部分图片了.现在贴一下布局代码:



    
    
        
        
  1. 开始将缓存出来的图片一分为2:

     Bitmap leftBitmap = getLeftBitmap(bitmap);
            mLeft.setImageBitmap(leftBitmap);
    
            Bitmap rightBitmap = getRightBitmap(bitmap);
            mRight.setImageBitmap(rightBitmap);
    startOpenAnim();
    
    • getLeftBitmap()方法,代码如下:

       private Bitmap getLeftBitmap(Bitmap bitmap) {
              int width=(int) (bitmap.getWidth() / 2f + 0.5f);
              //画画需要白纸,Bitmap就是那张白纸
              Bitmap leftCopyBitmap = Bitmap.createBitmap(width, bitmap.getHeight(), bitmap.getConfig());
              //创建画布
              Canvas canvas=new Canvas(leftCopyBitmap);
              Matrix matrix = new Matrix();
              //画画需要画笔,创建画笔
              Paint paint=new Paint();
              canvas.drawBitmap(bitmap,matrix,paint);
              return leftCopyBitmap;
          }
      
    • getRightBitmap()方法,代码如下:

       private Bitmap getRightBitmap(Bitmap bitmap) {
              int width=(int) (bitmap.getWidth() / 2f + 0.5f);
              //画画需要白纸,Bitmap就是那张白纸
              Bitmap rightCopyBitmap = Bitmap.createBitmap(width, bitmap.getHeight(), bitmap.getConfig());
              //创建画布
               Canvas canvas=new Canvas(rightCopyBitmap);
              Matrix matrix=new Matrix();
              //要获取右半部分的图片则需要图片向左平移一半
              matrix.setTranslate(-width,0);
              //画画需要画笔,创建画笔
              Paint paint=new Paint();
              canvas.drawBitmap(bitmap,matrix,paint);
              return rightCopyBitmap;
          }
      
  2. 最后开启动画:代码如下

       private void startOpenAnim() {
            mMainContainer.setVisibility(View.GONE);
            mAnimContainer.setVisibility(View.VISIBLE);
            int leftWidth = mLeft.getWidth();
            int rightWidth = mRight.getWidth();
            ObjectAnimator leftAnim = ObjectAnimator.ofFloat(mLeft, "translationX", 0, -leftWidth);
            ObjectAnimator rightAnim = ObjectAnimator.ofFloat(mRight, "translationX",0, rightWidth);
            ObjectAnimator mainAnim = ObjectAnimator.ofFloat(mAnimContainer, "alpha", 1, 0);
            AnimatorSet set=new AnimatorSet();
            set.setDuration(3*1000);
            set.playTogether(leftAnim,rightAnim,mainAnim);
            set.start();
        }
    

    到这里就大功告成了.

    ​ 所有代码如下:

 package com.kira.opendooranimdemo;
   import android.animation.AnimatorSet;
   import android.animation.ObjectAnimator;
   import android.graphics.Bitmap;
   import android.graphics.Canvas;
   import android.graphics.Matrix;
   import android.graphics.Paint;
   import android.os.Bundle;
   import android.support.v7.app.AppCompatActivity;
   import android.util.Log;
   import android.view.View;
   import android.widget.ImageView;
   import android.widget.LinearLayout;
   import android.widget.RelativeLayout;
   public class MainActivity extends AppCompatActivity {
       private ImageView mLeft;
       private ImageView mRight;
       private LinearLayout mAnimContainer;
       private RelativeLayout mMainContainer;
       private static final String TAG = "MainActivity";

       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
           initView();

          // initNewData();
       }

       @Override
       public void onWindowFocusChanged(boolean hasFocus) {
           super.onWindowFocusChanged(hasFocus);
           initData();
       }

       private void initNewData() {
           int height=0;
           for (int i = 0; i < mMainContainer.getChildCount(); i++) {
               height+=mMainContainer.getChildAt(i).getHeight();
           }
           //创建对应大小的Bitmap
           Log.e(TAG, "initNewData: "+mMainContainer.getWidth()+"....."+height);
           Bitmap bitmap = Bitmap.createBitmap(300, 500, Bitmap.Config.ARGB_8888);
           Bitmap leftBitmap = getLeftBitmap(bitmap);
           mLeft.setImageBitmap(leftBitmap);

           Bitmap rightBitmap = getRightBitmap(bitmap);
           mRight.setImageBitmap(rightBitmap);
           startOpenAnim();
       }

       private void initData() {
           //缓存图像
           mMainContainer.setDrawingCacheEnabled(true);  //开启缓存
           mMainContainer.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); //设置缓存的质量
   //        mMainContainer.buildDrawingCache();
   //        mMainContainer.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
   //                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
   //        mMainContainer.layout(0, 0, mMainContainer.getMeasuredWidth(), mMainContainer.getMeasuredHeight());
           Bitmap bitmap = mMainContainer.getDrawingCache();


           Bitmap leftBitmap = getLeftBitmap(bitmap);
           mLeft.setImageBitmap(leftBitmap);

           Bitmap rightBitmap = getRightBitmap(bitmap);
           mRight.setImageBitmap(rightBitmap);

           startOpenAnim();
       }

       private void startOpenAnim() {
           mMainContainer.setVisibility(View.GONE);
           mAnimContainer.setVisibility(View.VISIBLE);
           int leftWidth = mLeft.getWidth();
           int rightWidth = mRight.getWidth();
           ObjectAnimator leftAnim = ObjectAnimator.ofFloat(mLeft, "translationX", 0, -leftWidth);
           ObjectAnimator rightAnim = ObjectAnimator.ofFloat(mRight, "translationX",0, rightWidth);
           ObjectAnimator mainAnim = ObjectAnimator.ofFloat(mAnimContainer, "alpha", 1, 0);
           AnimatorSet set=new AnimatorSet();
           set.setDuration(3*1000);
           set.playTogether(leftAnim,rightAnim,mainAnim);
           set.start();
       }

       private Bitmap getRightBitmap(Bitmap bitmap) {
           int width=(int) (bitmap.getWidth() / 2f + 0.5f);
           //画画需要白纸,Bitmap就是那张白纸
           Bitmap rightCopyBitmap = Bitmap.createBitmap(width, bitmap.getHeight(), bitmap.getConfig());
           //创建画布
            Canvas canvas=new Canvas(rightCopyBitmap);
           Matrix matrix=new Matrix();
           //要获取右半部分的图片则需要图片向左平移一半
           matrix.setTranslate(-width,0);
           //画画需要画笔,创建画笔
           Paint paint=new Paint();
           canvas.drawBitmap(bitmap,matrix,paint);
           return rightCopyBitmap;
       }

       private Bitmap getLeftBitmap(Bitmap bitmap) {
           int width=(int) (bitmap.getWidth() / 2f + 0.5f);
           //画画需要白纸,Bitmap就是那张白纸
           Bitmap leftCopyBitmap = Bitmap.createBitmap(width, bitmap.getHeight(), bitmap.getConfig());
           //创建画布
           Canvas canvas=new Canvas(leftCopyBitmap);
           Matrix matrix = new Matrix();
           //画画需要画笔,创建画笔
           Paint paint=new Paint();
           canvas.drawBitmap(bitmap,matrix,paint);
           return leftCopyBitmap;


       }

       private void initView() {
           mLeft = (ImageView) findViewById(R.id.iv_left);
           mRight = (ImageView) findViewById(R.id.iv_right);
           mAnimContainer = (LinearLayout) findViewById(R.id.anim_container);
           mMainContainer = (RelativeLayout) findViewById(R.id.main_container);
       }
   }

布局代码如下:



    
    
        
        

你可能感兴趣的:(Android之开门动画的实现)