View — 应用截图(Android)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Love667767/article/details/82902610


一、概述

需求:在分享的时候,可能会遇到需要 截取整个屏幕截取屏幕一部分 的需求;

截图方案主要有以下两种:

  1. 开启 View.DrawingCache()
  2. 调用 View.draw()

二、View的缓存

2.1 使用条件

  1. 使用DrawingCache,缓存的View需要显示在界面上。如果View没有添加到界面上或者没有显示(绘制)过,则 View.buildDrawingCache() 会失败。

  2. 缓存的View的大小不能超过 屏幕宽 * 屏幕高 * 4 的大小,否则会抛出异常;

    // View.class
    private void buildDrawingCacheImpl(boolean autoScale) {
        mCachingFailed = false;
        int width = mRight - mLeft;
        int height = mBottom - mTop;
    	// ...代码省略...
        final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
        final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
        final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
    
        final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
        // 缓存的大小 = 屏幕宽 * 屏幕高  * 4
        final long drawingCacheSize = ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
        // projectedBitmapSize > drawingCacheSize
        if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
            if (width > 0 && height > 0) {
                Log.w(VIEW_LOG_TAG, getClass().getSimpleName() + " not displayed because it is"
                        + " too large to fit into a software layer (or drawing cache), needs "
                        + projectedBitmapSize + " bytes, only "
                        + drawingCacheSize + " available");
            }
            destroyDrawingCache();
            mCachingFailed = true;
            return;
        }
    	// ...代码省略...
    }
    

2.2 使用场景

这种方式比较适合对应用界面或者某一部分的截图。

2.3 步骤

view.setDrawingCacheEnabled(true);
//启用DrawingCache并创建位图
view.buildDrawingCache();  
Bitmap cacheBitmap = view.getDrawingCache();
//创建一个DrawingCache的拷贝,因为DrawingCache得到的位图在禁用后会被回收
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); 
//禁用DrawingCahce否则会影响性能
view.setDrawingCacheEnabled(false); 

2.4 缺点

如果所需的截图没有显示在界面上(或者不可见),则即使开启View的缓存仍然不能获取所需的截图;


三、View.draw()

3.1 使用场景

分享的图没有显示在可见视图上 (分享的视图与可见视图不一致);

使用 Java代码 或者 inflate 创建;但是需要先指定View的大小,即调用下面的方法。

public void layoutView(View view, int width, int height) {		
    // validate view.width and view.height
	view.layout(0, 0, width, height);		
	int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);		
	int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);		
	// validate view.measurewidth and view.measureheight		
	view.measure(measuredWidth, measuredHeight);		
	view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}

调用完上面的方法后,View和其内部的子View就有了实际大小,即完成了布局(相当于添加到了界面上)。
接着就可以创建位图并在上面绘制了:

// 创建截图
public void createBitmap(View view) {
    int viewWidth = view.getMeasuredWidth();
    int viewHeight = view.getMeasuredHeight();
    if (viewWidth > 0 && viewHeight > 0) {
    	// 这里的bitmap就是所需的截图
    	Bitmap bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Config.ARGB_8888);	
    	Canvas canvas = new Canvas(bitmap );	
    	view.draw(canvas);
    }
}


四、参考

Android应用截图两种方法

猜你喜欢

转载自blog.csdn.net/Love667767/article/details/82902610