Android 带动画截屏

Android 截屏带动画,缩小移动至屏幕右上角消失

传示例小视频没成功,就直接代码解释吧

最关键的几个操作,(思路:一般情况下,绝大多数View在绘制都可以设置缓存,我获取缓存,会返回给我们一个Bitmap对象,这个Bitmap对象是就是我们需要的)下面看下几个关键操作

 //设置缓存
  view.setDrawingCacheEnabled(true);
  view.buildDrawingCache();
    //从缓存中获取当前屏幕的图片
  view.getDrawingCache();
   //清楚缓存
  destroyDrawingCache();

这里我单独写了一个类来处理截屏,这是构造方法

  public ScreenGraspUtils(Activity activity, View view) {
        this.activity = activity;
        this.LayoutTop = view;
    }

下面是截屏方法

   public void grasp() {
        File appDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "xxPic");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = "推广二维码.jpg";
        File file = new File(appDir, fileName);
        if (file.exists()) {
            if (file.length() < 10) {
                file.delete();
            } else {
                ToastUtil.showToast(activity, "二维码已经存在了,请在相册中查看");
                 return;
            }
        }
        //先隐藏顶部的导航栏
        LayoutTop.setVisibility(View.INVISIBLE);

        //获取当前屏幕的大小
        int width = activity.getWindow().getDecorView().getRootView().getWidth();
        int height = activity.getWindow().getDecorView().getRootView().getHeight();
        //生成相同大小的图片

        temBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        temBitmap.setDensity(activity.getResources().getDisplayMetrics().densityDpi);
        //找到当前页面的跟布局
        View view = activity.getWindow().getDecorView().getRootView();
        //先清缓存
        //view.destroyDrawingCache();
        //设置缓存
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        //从缓存中获取当前屏幕的图片
        temBitmap = view.getDrawingCache();
        // 获取状态栏高度
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        // 获取屏幕长和高
        screenwidth = activity.getResources().getDisplayMetrics().widthPixels;
        screenheight = activity.getResources().getDisplayMetrics().heightPixels;
        // 去掉标题栏
        bitmap = Bitmap.createBitmap(temBitmap, 0, statusBarHeight, screenwidth, screenheight - statusBarHeight);

        //清缓存
        view.destroyDrawingCache();
        view.setDrawingCacheEnabled(false);
        //将截屏的bitmap保存至本地
        saveImage(bitmap);
        //构造一个ImageView对象,用于显示一个截屏的动画
        imageView = new ImageView(activity);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        imageView.setImageBitmap(bitmap);
        //将ImageView对象添加到当前Activity所在界面
        activity.addContentView(imageView, params);
        //构造一个图片的像素矩阵,通过操作矩阵变化,来实现图片缩小移动的动画
        mScaleMatrix = new Matrix();
        //设置图片的变换方式为矩阵变换
        imageView.setScaleType(ImageView.ScaleType.MATRIX);
        //这是一个自定义的定时器,具体实现待会看下面
        TimeUtils.getTaskTimer(1000, 25, new TimeUtils.ITimerTask() {//矩阵变化时间为1s,没25ms发送一次,一共会发送40次,也就是变化40次,手机性能差的,可能1s没有执行完成,在下面的onFished移除任务,没到40次几页就不会执行了,
            @Override
            public void onTask(long leftTime) {
                sX = screenwidth;//图片变化中心点的X
                sY = 0;//图片变化中心的Y坐标
                mScaleMatrix.postScale(0.9f, 0.9f, sX, sY);//改变图片的像素矩阵,结果是0.9倍缩放,当然就是变小了
                imageView.setImageMatrix(mScaleMatrix);//缩小图片
            }
            @Override
            public void onFished() {
                TimeUtils.setTimer(null);//移除任务
                //移除跟布局锁添加的imageview,
                ((ViewGroup) activity.getWindow().getDecorView().getRootView()).removeView(imageView);
                //销毁ImageView所占用的bitmap资源,不然imageview不会移除,下次再次截屏会覆盖在上面
                imageView.setImageBitmap(null);
                //下面两个都是回收,不回收会增加内存消耗,(建议不用就收回)
                if (bitmap != null && !bitmap.isRecycled()) {
                    bitmap.recycle();//回收bitmap
                    bitmap = null;
                }
                if (temBitmap != null && !temBitmap.isRecycled()) {
                    temBitmap.recycle();//回收bitmap
                    temBitmap = null;
                }
                //这是一个顶部带返回按钮和保存二维码的导航栏,截屏前为了截取的图片没有这些,开始隐藏了,现在还原,保证用户可以正常操作界面
                LayoutTop.setVisibility(View.VISIBLE);
            }
        }).start();//start()一定不能忘记,这是开启定时器
    }

下面是保存图片,写入文件的权限,我这里就没有申请了,需要的自己申请下也很简单

  private void saveImage(Bitmap bmp) {
        if (bmp == null) return;
        File appDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "xxPic");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = "推广二维码.jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            //系统广播,刷新相册,在相册中才能看到截屏
            activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("/sdcard/xxPic/推广二维码.jpg"))));
            ToastUtil.showToast(activity, "已保存至 xxPic/推广二维码.jpg");
        } catch (FileNotFoundException e) {
            ToastUtil.showToast(activity, "保存失败");
            e.printStackTrace();
        } catch (IOException e) {
            ToastUtil.showToast(activity, "保存失败");
            e.printStackTrace();
        }
    }

下面是定时器类

public class TimeUtils{
private static MyTimer mTimer;

    public static void setTimer(MyTimer myTimer){
        mTimer=myTimer;
    }

    public static MyTimer getTaskTimer(long millisInFuture, long countDownInterval, ITimerTask iTimerTask) {
        if (mTimer == null) {
            mTimer = new MyTimer(millisInFuture, countDownInterval, iTimerTask);
        } else {
            if (mTimer.isRunning()) {
                mTimer.cancel();
                mTimer = null;
                return new MyTimer(millisInFuture, countDownInterval, iTimerTask);
            }
        }
        return mTimer;
    }

    /**
     * 倒计时工具
     */
    public static class MyTimer extends CountDownTimer {
        private ITimerTask iTimerTask;
        private boolean isRunning;

        /**
         * @param millisInFuture    倒计时
         * @param countDownInterval 以多少毫秒的方式倒计时
         */
        public MyTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        /**
         * @param millisInFuture    倒计时
         * @param countDownInterval 以多少毫秒的方式倒计时
         * @param timerTask         倒计时开启后的任务接口
         */
        public MyTimer(long millisInFuture, long countDownInterval, ITimerTask timerTask) {
            super(millisInFuture, countDownInterval);
            this.iTimerTask = timerTask;
        }

        @Override
        public void onTick(long millisUntilFinished) {
            isRunning = true;
            iTimerTask.onTask(millisUntilFinished);
        }

        @Override
        public void onFinish() {
            if (iTimerTask != null)
                iTimerTask.onFished();
            isRunning = false;
        }

        public boolean isRunning() {
            return isRunning;
        }

    }

    /**
     * 倒计时任务接口
     */
    public interface ITimerTask {
        /**
         * @param leftTime 倒计时剩余时间
         *                 倒计时开启后执行的任务
         */
        void onTask(long leftTime);

        /**
         * 倒计时结束
         */
        void onFished();
    }
}

到这里就搞定了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值