美文网首页
Android截图保存,并分享截图图片,截取ScrollView

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

作者: 奋斗小青年Jerome | 来源:发表于2018-12-19 16:17 被阅读50次

    最近项目需要做一个类似老虎股票的截图分享功能,仔细看了一下这个分享,是截取当前界面显示的内容成图片,并在图片底部拼接上二维码和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就行了.

    相关文章

      网友评论

          本文标题:Android截图保存,并分享截图图片,截取ScrollView

          本文链接:https://www.haomeiwen.com/subject/nbyjkqtx.html