Android截图保存,并分享截图图片,截取ScrollView

2018-12-19  本文已影响50人  奋斗小青年Jerome

最近项目需要做一个类似老虎股票的截图分享功能,仔细看了一下这个分享,是截取当前界面显示的内容成图片,并在图片底部拼接上二维码和logo等,最后将图片分享出去,截图如下


screenShotShare.gif

找了一圈,发现安卓截图分享,最常用的方式是截取到当前最顶层view的缓存图片,代码如下

        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap screenShotBm = view.getDrawingCache();
        view.destroyDrawingCache();//注意,这里需要释放缓存

用个ImageView,set一下,就能看到,这个screenShotBm就是我们刚才截取的这个屏幕的图片,需要注意的是,这个截图是包含了状态栏高度的,如果不需要可以减去这个状态栏高度

 private Bitmap drawComBitmap(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);// 允许当前窗口保存缓存信息,这样getDrawingCache()方法才会返回一个Bitmap
        if (null != view) {
            //获取顶部的bitmap
            int width = view.getMeasuredWidth();
            int statusBarHeight = getStatusBarHeight(activity);
            //去掉状态栏和导航栏的高度
            int height = view.getMeasuredHeight() - getNavigationBarHeight(activity) - statusBarHeight;
            //拼接图片
            Bitmap logoBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.screenshot_logo);
            Bitmap codeBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.screenshot_code);
            int logoHeight = logoBitmap.getHeight();
            int codeHeight = codeBitmap.getHeight();
            int codeWidth = codeBitmap.getWidth();
            mDefaultLogoBgHeight = logoHeight * 2;
            mBgHeight = height - mDefaultLogoBgHeight;
            Bitmap drawingCache = view.getDrawingCache();
            Bitmap topBitmap = Bitmap.createBitmap(drawingCache, 0, statusBarHeight, width, height);
            //绘制原始图片
            mNewb = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(mNewb);
            canvas.drawBitmap(topBitmap, 0, 0, null);
            //绘制底部背景
            canvas.drawRect(0, height, width, mBgHeight, mBitPaint);
            //绘制二维码和logo
            canvas.drawBitmap(logoBitmap, mDefaultMargin, (height - mDefaultLogoBgHeight / 2) - logoHeight / 2, null);
            canvas.drawBitmap(codeBitmap, width - codeWidth - mDefaultMargin, (height - mDefaultLogoBgHeight / 2) - codeHeight / 2, null);
            canvas.save(Canvas.ALL_SAVE_FLAG);
            canvas.restore();
            //释放资源
            view.destroyDrawingCache();
            drawingCache.recycle();
            logoBitmap.recycle();
            codeBitmap.recycle();
            topBitmap.recycle();
        }
        return mNewb;
    }

最后就是分享,调用分享(友盟),将此图片分享出去

第二种,截取ScrollView图片,并分享

这种截图稍微复杂一点,但是也没有特别复杂
首先看一下效果,是将一段文字添加到某张图片中,并将图片底部添加二维码和logo最终分享出去
我理解的之所以是用ScrollView,是因为中间的文字是可多可少的,文字长了,整个页面就是可以滑动的


screenshot.gif

首先看一下ScrollView的截图方式,ScrollView截图最重要的一点就是正确获取到整个ScrollView的真实高度

public Bitmap getScrollScreenShot(ScrollView view) {
        if (null != view) {
            int height = 0;
            //正确获取ScrollView
            for (int i = 0; i < view.getChildCount(); i++) {
                height += view.getChildAt(i).getHeight();
            }
            if (height > 0) {
                //创建保存缓存的bitmap
                Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), height, Bitmap.Config.RGB_565);
                //可以简单的把Canvas理解为一个画板 而bitmap就是块画布
                Canvas canvas = new Canvas(bitmap);
                //把view的内容都画到指定的画板Canvas上
                view.draw(canvas);
                return bitmap;
            }
        }

        return null;
    }

至于内容的拼接,有两种思考方式
第一种是使用Canvas去画,这个画的话就需要准确的计算顶部标题,时间,以及底部logo和二维码的正确坐标,调用API进行draw就可以了
第二种是使用layout布局,这里主要使用第二种方式

       public Bitmap sheareScroll() {
        ViewGroup rootView = findViewById(android.R.id.content);
        View inflate = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_screen_short, null);
        rootView.addView(inflate, 0);
        final ScrollView scrollView = inflate.findViewById(R.id.scrollView);
        inflate.post(new Runnable() {
            @Override
            public void run() {
                mScrollScreenShot = getScrollScreenShot(scrollView);
               
            }
        });

        return mScrollScreenShot;
    }

这里要注意的几点

  1. android.R.id.content 这个东西想必不陌生,它是一个FrameLayout,我们在任何一个窗口(界面),拿到它的最底层view,即DecorView,其实就是这个FrameLayout
  2. 使用LayoutInflater将这个layout加载出来,得到这个包含布局的view,这里该设置数据的设置数据,该获取id的获取id,这个R.layout.activity_screen_short布局中就是截图中显示的布局,包含顶部的标题,时间戳,以及内容布局,logo,二维码等
  3. rootView.addView(inflate, 0); 这里是很巧妙的一个做法,将inflate到的这个view添加到当前这个窗口的最底层,相当于手动动态的给当前的界面在最底层添加了一个布局进去,由于这个rootView是个FrameLayout,上层被内容遮挡,我们看不到这个添加到最底层的layout,最后截图的时候,就截这个添加进去的inflate这个view中的scrollView就可以了.

最后就是分享这个截图的Bitmap就行了.

上一篇下一篇

猜你喜欢

热点阅读