笔记24 | 一个中间打开界面的动画

前言和下载地址

更新技术公号的好处之一是它会逼着你去学习一个新的东西,今天是一个中间打开Activity效果的动画,可以保存当工具类直接使用!


一.先来看实现效果


二.主要代码

  • MainActivity

 
 
  1. findViewById(R.id.one).setOnClickListener(new View.OnClickListener() {

  2.            @Override

  3.            public void onClick(View v) {

  4.                ActivitySplitAnimationUtil.startActivity(Activity1.this, new Intent(Activity1.this, Activity2.class));

  5.            }

  6.        });

  • ActivitySplitAnimationUtil.java

 
 
  1. /**

  2. * Utility class to create a split activity animation

  3. *

  4. * @author Udi Cohen (@udinic)

  5. */

  6. public class ActivitySplitAnimationUtil {

  7.    public static Bitmap mBitmap = null;

  8.    private static int[] mLoc1;

  9.    private static int[] mLoc2;

  10.    private static ImageView mTopImage;

  11.    private static ImageView mBottomImage;

  12.    private static AnimatorSet mSetAnim;

  13.    /**

  14.     * Start a new Activity with a Split animation

  15.     *

  16.     * @param currActivity The current Activity

  17.     * @param intent       The Intent needed tot start the new Activity

  18.     * @param splitYCoord  The Y coordinate where we want to split the Activity on the animation. -1 will split the Activity equally

  19.     */

  20.    public static void startActivity(Activity currActivity, Intent intent, int splitYCoord) {

  21.        // Preparing the bitmaps that we need to show

  22.        prepare(currActivity, splitYCoord);

  23.        currActivity.startActivity(intent);

  24.        currActivity.overridePendingTransition(0, 0);

  25.    }

  26.    /**

  27.     * Start a new Activity with a Split animation right in the middle of the Activity

  28.     *

  29.     * @param currActivity The current Activity

  30.     * @param intent       The Intent needed tot start the new Activity

  31.     */

  32.    public static void startActivity(Activity currActivity, Intent intent) {

  33.        startActivity(currActivity, intent, -1);

  34.    }

  35.    /**

  36.     * Preparing the graphics on the destination Activity.

  37.     * Should be called on the destination activity on Activity#onCreate() BEFORE setContentView()

  38.     *

  39.     * @param destActivity the destination Activity

  40.     */

  41.    public static void prepareAnimation(final Activity destActivity) {

  42.        mTopImage = createImageView(destActivity, mBitmap, mLoc1);

  43.        mBottomImage = createImageView(destActivity, mBitmap, mLoc2);

  44.    }

  45.    /**

  46.     * 启动动画,显示目标Activity

  47.     * Should be called on the destination activity on Activity#onCreate() AFTER setContentView()

  48.     *

  49.     * @param destActivity the 目标 Activity

  50.     * @param duration The 持续时间 of the animation

  51.     * @param interpolator The interpulator to use for the animation. null for no interpulation.

  52.     */

  53.    public static void animate(final Activity destActivity, final int duration, final TimeInterpolator interpolator) {

  54.        // 在UI线程的消息队列上发布这个消息。我们需要对这些项目进行测量

  55.        new Handler().post(new Runnable() {

  56.            @Override

  57.            public void run() {

  58.                mSetAnim = new AnimatorSet();

  59.                mTopImage.setLayerType(View.LAYER_TYPE_HARDWARE, null);

  60.                mBottomImage.setLayerType(View.LAYER_TYPE_HARDWARE, null);

  61.                mSetAnim.addListener(new Animator.AnimatorListener() {

  62.                    @Override

  63.                    public void onAnimationStart(Animator animation) {

  64.                    }

  65.                    @Override

  66.                    public void onAnimationEnd(Animator animation) {

  67.                        clean(destActivity);

  68.                    }

  69.                    @Override

  70.                    public void onAnimationCancel(Animator animation) {

  71.                        clean(destActivity);

  72.                    }

  73.                    @Override

  74.                    public void onAnimationRepeat(Animator animation) {

  75.                    }

  76.                });

  77.                // Animating the 2 parts away from each other

  78.                Animator anim1 = ObjectAnimator.ofFloat(mTopImage, "translationY", mTopImage.getHeight() * -1);

  79.                Animator anim2 = ObjectAnimator.ofFloat(mBottomImage, "translationY", mBottomImage.getHeight());

  80.                if (interpolator != null) {

  81.                    anim1.setInterpolator(interpolator);

  82.                    anim2.setInterpolator(interpolator);

  83.                }

  84.                mSetAnim.setDuration(duration);

  85.                mSetAnim.playTogether(anim1, anim2);

  86.                mSetAnim.start();

  87.            }

  88.        });

  89.    }

  90.    /**

  91.     * 启动显示目标Activity的动画

  92.     * Should be called on the destination activity on Activity#onCreate() AFTER setContentView()

  93.     *

  94.     * @param destActivity the destination Activity

  95.     * @param duration The duration of the animation

  96.     */

  97.    public static void animate(final Activity destActivity, final int duration) {

  98.        animate(destActivity, duration, new DecelerateInterpolator());

  99.    }

  100.    /**

  101.     * Cancel an in progress animation

  102.     */

  103.    public static void cancel() {

  104.        if (mSetAnim != null)

  105.            mSetAnim.cancel();

  106.    }

  107.    /**

  108.     * Clean stuff

  109.     *

  110.     * @param activity The Activity where the animation is occurring

  111.     */

  112.    private static void clean(Activity activity) {

  113.        if (mTopImage != null) {

  114.            mTopImage.setLayerType(View.LAYER_TYPE_NONE, null);

  115.            try {

  116.                // If we use the regular removeView() we'll get a small UI glitch

  117.                activity.getWindowManager().removeViewImmediate(mBottomImage);

  118.            } catch (Exception ignored) {

  119.            }

  120.        }

  121.        if (mBottomImage != null) {

  122.            mBottomImage.setLayerType(View.LAYER_TYPE_NONE, null);

  123.            try {

  124.                activity.getWindowManager().removeViewImmediate(mTopImage);

  125.            } catch (Exception ignored) {

  126.            }

  127.        }

  128.        mBitmap = null;

  129.    }

  130.    /**

  131.     * 为动画制作图形

  132.     *

  133.     * @param currActivity the current Activity from where we start the new one

  134.     * @param splitYCoord  The Y coordinate where we want to split the activity. -1 will split the activity equally

  135.     */

  136.    private static void prepare(Activity currActivity, int splitYCoord) {

  137.        // 获取activity的内容并放入一个位图

  138.        View root = currActivity.getWindow().getDecorView().findViewById(android.R.id.content);

  139.        root.setDrawingCacheEnabled(true);

  140.        mBitmap = root.getDrawingCache();

  141.        // If the split Y coordinate is -1 - We'll split the activity equally

  142.        splitYCoord = (splitYCoord != -1 ? splitYCoord : mBitmap.getHeight() / 2);

  143.        if (splitYCoord > mBitmap.getHeight())

  144.            throw new IllegalArgumentException("Split Y coordinate [" + splitYCoord + "] exceeds the activity's height [" + mBitmap.getHeight() + "]");

  145.        // Set the location to put the 2 bitmaps on the destination activity

  146.        mLoc1 = new int[]{0, splitYCoord, root.getTop()};

  147.        mLoc2 = new int[]{splitYCoord, mBitmap.getHeight(), root.getTop()};

  148.    }

  149.    /**

  150.     * 创建一个映像,在目标Activity中包含动画的一个部分

  151.     *

  152.     * @param destActivity The destination activity

  153.     * @param bmp          The Bitmap of the part we want to add to the destination activity

  154.     * @param loc          The location this part should be on the screen

  155.     * @return

  156.     */

  157.    private static ImageView createImageView(Activity destActivity, Bitmap bmp, int loc[]) {

  158.        MyImageView imageView = new MyImageView(destActivity);

  159.        imageView.setImageBitmap(bmp);

  160.        imageView.setImageOffsets(bmp.getWidth(), loc[0], loc[1]);                    

  161.        WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();

  162.        windowParams.gravity = Gravity.TOP;

  163.        windowParams.x = 0;

  164.        windowParams.y = loc[2] + loc[0];

  165.        windowParams.height = loc[1] - loc[0];

  166.        windowParams.width = bmp.getWidth();

  167.        windowParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

  168.        windowParams.format = PixelFormat.TRANSLUCENT;

  169.        windowParams.windowAnimations = 0;

  170.        destActivity.getWindowManager().addView(imageView, windowParams);

  171.        return imageView;

  172.    }

  173.    /**

  174.     * MyImageView

  175.     * Extended ImageView that draws just part of an image, base on start/end position  

  176.     */

  177.    private static class MyImageView extends ImageView

  178.    {

  179.        private Rect mSrcRect;

  180.        private Rect mDstRect;

  181.        private Paint mPaint;      

  182.        public MyImageView(Context context)

  183.        {

  184.            super(context);

  185.            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

  186.        }

  187.        /**

  188.         * 设置位图来控制可见区域

  189.         *

  190.         * @param width        The bitmap image

  191.         * @param bmp          The start Y position

  192.         * @param loc          The end Y position

  193.         * @return

  194.         */

  195.        public void setImageOffsets(int width, int startY, int endY)

  196.        {

  197.            mSrcRect = new Rect(0, startY, width, endY);

  198.            mDstRect = new Rect(0, 0, width, endY - startY);

  199.        }

  200.        @Override

  201.        protected void onDraw(Canvas canvas)

  202.        {

  203.            Bitmap bm = null;

  204.            Drawable drawable = getDrawable();

  205.            if (null != drawable && drawable instanceof BitmapDrawable)

  206.            {

  207.                bm = ((BitmapDrawable)drawable).getBitmap();

  208.            }

  209.            if (null == bm)

  210.            {

  211.                super.onDraw(canvas);

  212.            }

  213.            else

  214.            {

  215.                canvas.drawBitmap(bm, mSrcRect, mDstRect, mPaint);

  216.            }

  217.        }      

  218.    }

  219. }


笔记23 | 复习for/while/do...while的几种循环用法

笔记22 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(三)

笔记21 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(二)

笔记20 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(一)

笔记19 | 利用MediaRecorder实现录像


END



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值