android中的截图

         在做项目的时候,产品提出了一个需求就是分享图片到微信或者朋友圈。乍一眼看到这个需求,觉得so easy呀,第三方都提供了对应的API并且自己也封装好了的。谁知道真正在做的时候一堆问题,本来1个小时应该搞定的需要害我整整搞了两天。算了,废话不多说了,直接上代码。

注意:我要分享出去的图在界面上不可见,同时要自己加上二维码和一些文字说明

在提供解决方案前,我先贴几个实现其他功能的代码作为笔记

实现截屏(当前屏幕):

​

   /**
     * @return 截图
     */
    public static Bitmap getBitmap(Activity activity) {
        int width = activity.getWindow().getDecorView().getRootView().getWidth();
        int height = activity.getWindow().getDecorView().getRootView().getHeight();
        View view = activity.getWindow().getDecorView().getRootView();
        view.setDrawingCacheEnabled(false);
        view.buildDrawingCache();
        Bitmap temBitmap = view.getDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(temBitmap, 0, 0, width, height);
        view.destroyDrawingCache();//不清空,第二次截屏则使用的是缓存的同一张。
        return Util.cropBitmap(bitmap, FontUtil.dip2px(activity, 44f) + Util.getStatusHeight(activity), FontUtil.dip2px(activity, 49f));
    }

[点击并拖拽以移动]
​

实现View截图(View可见):

   /**
     * 把View绘制到Bitmap上
     *
     * @return 返回Bitmap对象
     */
    public static Bitmap getPostViewBitmap(View v) {
        v.clearFocus();
        v.setPressed(false);
        boolean willNotCache = v.willNotCacheDrawing();
        v.setWillNotCacheDrawing(false);
        int color = v.getDrawingCacheBackgroundColor();
        v.setDrawingCacheBackgroundColor(0);
        if (color != 0) {
            v.destroyDrawingCache();
        }
        v.buildDrawingCache();
        Bitmap cacheBitmap = v.getDrawingCache();
        if (cacheBitmap == null) {
            return null;
        }
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
        v.destroyDrawingCache();
        v.setWillNotCacheDrawing(willNotCache);
        v.setDrawingCacheBackgroundColor(color);
        return bitmap;
    }

实现View截图(View不可见):

在实现这个的时候比较坑,在网上搜到的大部分都是我上面的第二种,但是大部分的人都不会告诉你截图成功的前提是该View是可见的。导致我在实现这个功能的时候获取到的bitmap永远是空

实现这个功能要分几个步骤:

1.测量View的宽高

    private static void layoutView(View v, int width, int height) {
        v.layout(0, 0, width, height);
        int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
        v.measure(measuredWidth, measuredHeight);
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    }

2.加载View的内容数据

3.生成bitmap

public static void getBitmap(View v, String rmb, int height) {
        int measuredWidth = v.getWidth();
        int measuredHeight = height;
        if (measuredWidth > 0) {
            Bitmap bmp = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(bmp);
            c.drawColor(Color.WHITE);
            v.layout(0, 0, measuredWidth, measuredHeight);
            v.draw(c);
            new PostShare(v.getContext(), null, null, null, PostShare.ShareType.IMAGE, 1, bmp).share(SHARE_MEDIA.WEIXIN_CIRCLE);
        }
    }

注意,最好是先测量再填充数据。

回到前头,我在做的时候,条件性的把显示区域用ImageView来显示,结果图片是显示出来的,但是图片由于太长,导致宽度无法与下面的自己填充的内容进行适配,所以这个方案最后被pass掉了,最后我采用Webview来进行处理,因为Webvie可以自适应屏幕大小,所以不存在适配的问题。

public static void shareFictionBitmap(Context context, String bkH5, String title, String content, String webUrl, String qrUrl, String rmb) {
        MyToast.showCenterSortToast(context, "图片生成中");
        DisplayMetrics metric = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels;// 屏幕宽度(像素)
        View view = LayoutInflater.from(context).inflate(R.layout.share_fiction, null);
        layoutView(view, width, 4500);
        WebView webView = view.findViewById(R.id.fiction_view);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setUseWideViewPort(true);//设置webview推荐使用的窗口
        webSettings.setLoadWithOverviewMode(true);//设置webview加载的页面的模式
        webSettings.setDisplayZoomControls(false);//隐藏webview缩放按钮
        webSettings.setJavaScriptEnabled(true); // 设置支持javascript脚本
        webSettings.setAllowFileAccess(true); // 允许访问文件
        webSettings.setBuiltInZoomControls(true); // 设置显示缩放按钮
        webSettings.setSupportZoom(true); // 支持缩放
        webSettings.setBuiltInZoomControls(true);
        webView.getSettings().setUseWideViewPort(true);
        webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        webView.getSettings().setLoadWithOverviewMode(true);
        webView.getSettings().setBlockNetworkImage(false);//解决图片不显示
        ImageView tvQR = view.findViewById(R.id.fiction_qr);
        webView.loadUrl(webUrl);
        tvQR.setImageBitmap(EncodingUtils.createQRCode(qrUrl, 1000, 1000, null));
        final boolean[] isShow = {true};
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView webView, int newProgress) {
                super.onProgressChanged(webView, newProgress);
                if (newProgress == 100 && isShow[0]) {
                    isShow[0] = false;
                    new Thread(() -> {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        ((Activity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                getBitmap(view, rmb, 4500);
                            }
                        });
                    }).start();
                }
            }
        });
    }

最终图片被成功的分享出去了,在这里还需要注意的一点就是,因为webview全部加载完毕需要时间,所以我们必须等webview加载完成后才可以对View进行截图,否则的话,截图出去的内容页很可能是黑色的,那是因为内容没有被截取到。

 

 

 

 

 

 

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值