DevUtils Github
CapturePictureUtils 截图工具类
支持 View、Activity、FrameLayout、RelativeLayout、LinearLayout、ListView、GridView、ScrollView、HorizontalScrollView、NestedScrollView、WebView、RecyclerView(GridLayoutManager、LinearLayoutManager、StaggeredGridLayoutManager)
截图工具类 -> CapturePictureUtils.java
方法注释
setBitmapConfig设置 Bitmap ConfigsetBackgroundColor设置 Canvas 背景色setPaint设置画笔snapshotWithStatusBar获取当前屏幕截图, 包含状态栏 ( 顶部灰色 TitleBar 高度, 没有设置 android:theme 的 NoTitleBar 时会显示 )snapshotWithoutStatusBar获取当前屏幕截图, 不包含状态栏 ( 如果 android:theme 全屏, 则截图无状态栏 )enableSlowWholeDocumentDraw关闭 WebView 优化snapshotByWebView截图 WebViewsnapshotByView通过 View 绘制为 BitmapsnapshotByViewCache通过 View Cache 绘制为 BitmapsnapshotByLinearLayout通过 LinearLayout 绘制为 BitmapsnapshotByFrameLayout通过 FrameLayout 绘制为 BitmapsnapshotByRelativeLayout通过 RelativeLayout 绘制为 BitmapsnapshotByScrollView通过 ScrollView 绘制为 BitmapsnapshotByHorizontalScrollView通过 HorizontalScrollView 绘制为 BitmapsnapshotByNestedScrollView通过 NestedScrollView 绘制为 BitmapsnapshotByListView通过 ListView 绘制为 BitmapsnapshotByGridView通过 GridView 绘制为 BitmapsnapshotByRecyclerView通过 RecyclerView 绘制为 Bitmap
package dev
.utils
.app
;
import android
.app
.Activity
;
import android
.content
.Context
;
import android
.graphics
.Bitmap
;
import android
.graphics
.Canvas
;
import android
.graphics
.Color
;
import android
.graphics
.Matrix
;
import android
.graphics
.Paint
;
import android
.graphics
.Picture
;
import android
.graphics
.Point
;
import android
.graphics
.Rect
;
import android
.os
.Build
;
import android
.support
.annotation
.ColorInt
;
import android
.support
.v4
.widget
.NestedScrollView
;
import android
.support
.v7
.widget
.GridLayoutManager
;
import android
.support
.v7
.widget
.LinearLayoutManager
;
import android
.support
.v7
.widget
.RecyclerView
;
import android
.support
.v7
.widget
.StaggeredGridLayoutManager
;
import android
.util
.DisplayMetrics
;
import android
.view
.View
;
import android
.view
.ViewGroup
;
import android
.view
.WindowManager
;
import android
.webkit
.WebView
;
import android
.widget
.FrameLayout
;
import android
.widget
.GridView
;
import android
.widget
.HorizontalScrollView
;
import android
.widget
.LinearLayout
;
import android
.widget
.ListAdapter
;
import android
.widget
.ListView
;
import android
.widget
.RelativeLayout
;
import android
.widget
.ScrollView
;
import dev
.DevUtils
;
import dev
.utils
.LogPrintUtils
;
public final class CapturePictureUtils {
private CapturePictureUtils() {
}
private static final String TAG
= CapturePictureUtils
.class.getSimpleName();
private static Bitmap
.Config BITMAP_CONFIG
= Bitmap
.Config
.RGB_565
;
private static int BACKGROUND_COLOR
= Color
.TRANSPARENT
;
private static Paint PAINT
= new Paint();
public static void setBitmapConfig(final Bitmap
.Config config
) {
if (config
== null
) return;
BITMAP_CONFIG
= config
;
}
public static void setBackgroundColor(@ColorInt final int backgroundColor
) {
BACKGROUND_COLOR
= backgroundColor
;
}
public static void setPaint(final Paint paint
) {
if (paint
== null
) return;
PAINT
= paint
;
}
public static Bitmap
snapshotWithStatusBar(final Activity activity
) {
try {
View view
= activity
.getWindow().getDecorView();
view
.setDrawingCacheEnabled(true);
view
.buildDrawingCache();
Bitmap cacheBitmap
= view
.getDrawingCache();
if (cacheBitmap
== null
) return null
;
int[] widthHeight
= getScreenWidthHeight();
Rect frame
= new Rect();
activity
.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame
);
Bitmap bitmap
= Bitmap
.createBitmap(cacheBitmap
, 0, 0, widthHeight
[0], widthHeight
[1]);
view
.destroyDrawingCache();
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotWithStatusBar");
}
return null
;
}
public static Bitmap
snapshotWithoutStatusBar(final Activity activity
) {
try {
View view
= activity
.getWindow().getDecorView();
view
.setDrawingCacheEnabled(true);
view
.buildDrawingCache();
Bitmap cacheBitmap
= view
.getDrawingCache();
if (cacheBitmap
== null
) return null
;
int[] widthHeight
= getScreenWidthHeight();
int statusBarHeight
= getStatusBarHeight(activity
);
Rect frame
= new Rect();
activity
.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame
);
Bitmap bitmap
= Bitmap
.createBitmap(cacheBitmap
, 0, statusBarHeight
, widthHeight
[0], widthHeight
[1] - statusBarHeight
);
view
.destroyDrawingCache();
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotWithoutStatusBar");
}
return null
;
}
public static void enableSlowWholeDocumentDraw() {
if (Build
.VERSION
.SDK_INT
>= Build
.VERSION_CODES
.LOLLIPOP
) {
android
.webkit
.WebView
.enableSlowWholeDocumentDraw();
}
}
public static Bitmap
snapshotByWebView(final WebView webView
) {
return snapshotByWebView(webView
, Integer
.MAX_VALUE
, BITMAP_CONFIG
, 0f);
}
public static Bitmap
snapshotByWebView(final WebView webView
, final int maxHeight
) {
return snapshotByWebView(webView
, maxHeight
, BITMAP_CONFIG
, 0f);
}
public static Bitmap
snapshotByWebView(final WebView webView
, final float scale
) {
return snapshotByWebView(webView
, Integer
.MAX_VALUE
, BITMAP_CONFIG
, scale
);
}
public static Bitmap
snapshotByWebView(final WebView webView
, final int maxHeight
, final Bitmap
.Config config
) {
return snapshotByWebView(webView
, maxHeight
, config
, 0f);
}
public static Bitmap
snapshotByWebView(final WebView webView
, final int maxHeight
,
final Bitmap
.Config config
, final float scale
) {
if (webView
!= null
&& config
!= null
) {
if (Build
.VERSION
.SDK_INT
>= Build
.VERSION_CODES
.LOLLIPOP
) {
try {
float newScale
= scale
;
if (newScale
<= 0) {
newScale
= webView
.getScale();
}
int width
= webView
.getWidth();
int height
= (int) (webView
.getContentHeight() * newScale
+ 0.5);
height
= (height
> maxHeight
) ? maxHeight
: height
;
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
webView
.draw(canvas
);
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByWebView - SDK_INT >= 21(5.0)");
}
} else {
try {
Picture picture
= webView
.capturePicture();
int width
= picture
.getWidth();
int height
= picture
.getHeight();
if (width
> 0 && height
> 0) {
height
= (height
> maxHeight
) ? maxHeight
: height
;
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
picture
.draw(canvas
);
return bitmap
;
}
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByWebView - SDK_INT < 21(5.0)");
}
}
}
return null
;
}
public static Bitmap
snapshotByView(final View view
) {
return snapshotByView(view
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByView(final View view
, final Bitmap
.Config config
) {
if (view
== null
|| config
== null
) return null
;
try {
Bitmap bitmap
= Bitmap
.createBitmap(view
.getWidth(), view
.getHeight(), config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
view
.layout(view
.getLeft(), view
.getTop(), view
.getRight(), view
.getBottom());
view
.draw(canvas
);
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByView");
}
return null
;
}
public static Bitmap
snapshotByViewCache(final View view
) {
if (view
== null
) return null
;
try {
view
.clearFocus();
view
.setPressed(false);
boolean willNotCache
= view
.willNotCacheDrawing();
view
.setWillNotCacheDrawing(false);
int color
= view
.getDrawingCacheBackgroundColor();
view
.setDrawingCacheBackgroundColor(0);
if (color
!= 0) {
view
.destroyDrawingCache();
}
view
.buildDrawingCache();
Bitmap cacheBitmap
= view
.getDrawingCache();
if (cacheBitmap
== null
) return null
;
Bitmap bitmap
= Bitmap
.createBitmap(cacheBitmap
);
view
.destroyDrawingCache();
view
.setWillNotCacheDrawing(willNotCache
);
view
.setDrawingCacheBackgroundColor(color
);
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByViewCache");
}
return null
;
}
public static Bitmap
snapshotByLinearLayout(final LinearLayout linearLayout
) {
return snapshotByLinearLayout(linearLayout
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByLinearLayout(final LinearLayout linearLayout
, final Bitmap
.Config config
) {
return snapshotByView(linearLayout
, config
);
}
public static Bitmap
snapshotByFrameLayout(final FrameLayout frameLayout
) {
return snapshotByFrameLayout(frameLayout
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByFrameLayout(final FrameLayout frameLayout
, final Bitmap
.Config config
) {
return snapshotByView(frameLayout
, config
);
}
public static Bitmap
snapshotByRelativeLayout(final RelativeLayout relativeLayout
) {
return snapshotByRelativeLayout(relativeLayout
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByRelativeLayout(final RelativeLayout relativeLayout
, final Bitmap
.Config config
) {
return snapshotByView(relativeLayout
, config
);
}
public static Bitmap
snapshotByScrollView(final ScrollView scrollView
) {
return snapshotByScrollView(scrollView
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByScrollView(final ScrollView scrollView
, final Bitmap
.Config config
) {
if (scrollView
== null
|| config
== null
) return null
;
try {
View view
= scrollView
.getChildAt(0);
int width
= view
.getWidth();
int height
= view
.getHeight();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
scrollView
.layout(0, 0, scrollView
.getMeasuredWidth(),
scrollView
.getMeasuredHeight());
scrollView
.draw(canvas
);
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByScrollView");
}
return null
;
}
public static Bitmap
snapshotByHorizontalScrollView(final HorizontalScrollView scrollView
) {
return snapshotByHorizontalScrollView(scrollView
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByHorizontalScrollView(final HorizontalScrollView scrollView
, final Bitmap
.Config config
) {
if (scrollView
== null
|| config
== null
) return null
;
try {
View view
= scrollView
.getChildAt(0);
int width
= view
.getWidth();
int height
= view
.getHeight();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
scrollView
.layout(0, 0, scrollView
.getMeasuredWidth(),
scrollView
.getMeasuredHeight());
scrollView
.draw(canvas
);
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByHorizontalScrollView");
}
return null
;
}
public static Bitmap
snapshotByNestedScrollView(final NestedScrollView scrollView
) {
return snapshotByNestedScrollView(scrollView
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByNestedScrollView(final NestedScrollView scrollView
, final Bitmap
.Config config
) {
if (scrollView
== null
|| config
== null
) return null
;
try {
View view
= scrollView
.getChildAt(0);
int width
= view
.getWidth();
int height
= view
.getHeight();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
scrollView
.layout(0, 0, scrollView
.getMeasuredWidth(),
scrollView
.getMeasuredHeight());
scrollView
.draw(canvas
);
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByNestedScrollView");
}
return null
;
}
public static Bitmap
snapshotByListView(final ListView listView
) {
return snapshotByListView(listView
, BITMAP_CONFIG
);
}
public static Bitmap
snapshotByListView(final ListView listView
, final Bitmap
.Config config
) {
if (listView
== null
|| config
== null
) return null
;
try {
ListAdapter listAdapter
= listView
.getAdapter();
int itemCount
= listAdapter
.getCount();
if (itemCount
== 0) return null
;
int height
= 0;
int dividerHeight
= listView
.getDividerHeight();
Bitmap
[] bitmaps
= new Bitmap[itemCount
];
for (int i
= 0; i
< itemCount
; i
++) {
View childView
= listAdapter
.getView(i
, null
, listView
);
measureView(childView
, listView
.getWidth());
bitmaps
[i
] = canvasBitmap(childView
, config
);
height
+= childView
.getMeasuredHeight();
}
height
+= (dividerHeight
* (itemCount
- 1));
int width
= listView
.getMeasuredWidth();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendHeight
= 0;
for (int i
= 0, len
= bitmaps
.length
; i
< len
; i
++) {
Bitmap bmp
= bitmaps
[i
];
canvas
.drawBitmap(bmp
, 0, appendHeight
, PAINT
);
appendHeight
+= (bmp
.getHeight() + dividerHeight
);
bmp
.recycle();
bmp
= null
;
}
return bitmap
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByListView");
}
return null
;
}
public static Bitmap
snapshotByGridView(final GridView gridView
) {
return snapshotByGridView(gridView
, BITMAP_CONFIG
, false);
}
public static Bitmap
snapshotByGridView(final GridView gridView
, final Bitmap
.Config config
) {
return snapshotByGridView(gridView
, config
, false);
}
public static Bitmap
snapshotByGridView(final GridView gridView
, final Bitmap
.Config config
, final boolean listViewEffect
) {
if (gridView
== null
|| config
== null
) return null
;
if (Build
.VERSION
.SDK_INT
< Build
.VERSION_CODES
.JELLY_BEAN
) return null
;
try {
ListAdapter listAdapter
= gridView
.getAdapter();
int itemCount
= listAdapter
.getCount();
if (itemCount
== 0) return null
;
int height
= 0;
int numColumns
= gridView
.getNumColumns();
int horizontalSpacing
= gridView
.getHorizontalSpacing();
int verticalSpacing
= gridView
.getVerticalSpacing();
Bitmap
[] bitmaps
= new Bitmap[itemCount
];
if (listViewEffect
) {
for (int i
= 0; i
< itemCount
; i
++) {
View childView
= listAdapter
.getView(i
, null
, gridView
);
measureView(childView
, gridView
.getWidth());
bitmaps
[i
] = canvasBitmap(childView
, config
);
height
+= childView
.getMeasuredHeight();
}
height
+= (verticalSpacing
* (itemCount
- 1));
int width
= gridView
.getMeasuredWidth();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendHeight
= 0;
for (int i
= 0, len
= bitmaps
.length
; i
< len
; i
++) {
Bitmap bmp
= bitmaps
[i
];
canvas
.drawBitmap(bmp
, 0, appendHeight
, PAINT
);
appendHeight
+= (bmp
.getHeight() + verticalSpacing
);
bmp
.recycle();
bmp
= null
;
}
return bitmap
;
} else {
int lineNumber
= getMultiple(itemCount
, numColumns
);
int childWidth
= (gridView
.getWidth() - (numColumns
- 1) * horizontalSpacing
) / numColumns
;
int[] rowHeightArrays
= new int[lineNumber
];
int tempHeight
;
for (int i
= 0; i
< lineNumber
; i
++) {
tempHeight
= 0;
for (int j
= 0; j
< numColumns
; j
++) {
int position
= i
* numColumns
+ j
;
if (position
< itemCount
) {
View childView
= listAdapter
.getView(position
, null
, gridView
);
measureView(childView
, childWidth
);
bitmaps
[position
] = canvasBitmap(childView
, config
);
int itemHeight
= childView
.getMeasuredHeight();
tempHeight
= Math
.max(itemHeight
, tempHeight
);
}
if (j
== numColumns
- 1) {
height
+= tempHeight
;
rowHeightArrays
[i
] = tempHeight
;
}
}
}
height
+= (verticalSpacing
* (lineNumber
- 1));
int width
= gridView
.getMeasuredWidth();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendHeight
= 0;
for (int i
= 0; i
< lineNumber
; i
++) {
int itemHeight
= rowHeightArrays
[i
];
for (int j
= 0; j
< numColumns
; j
++) {
int position
= i
* numColumns
+ j
;
if (position
< itemCount
) {
Bitmap bmp
= bitmaps
[position
];
int left
= j
* (horizontalSpacing
+ childWidth
);
Matrix matrix
= new Matrix();
matrix
.postTranslate(left
, appendHeight
);
canvas
.drawBitmap(bmp
, matrix
, PAINT
);
bmp
.recycle();
bmp
= null
;
}
if (j
== numColumns
- 1) {
appendHeight
+= itemHeight
+ verticalSpacing
;
}
}
}
return bitmap
;
}
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByGridView");
}
return null
;
}
public static Bitmap
snapshotByRecyclerView(final RecyclerView recyclerView
) {
return snapshotByRecyclerView(recyclerView
, BITMAP_CONFIG
, 0, 0);
}
public static Bitmap
snapshotByRecyclerView(final RecyclerView recyclerView
,
final Bitmap
.Config config
) {
return snapshotByRecyclerView(recyclerView
, config
, 0, 0);
}
public static Bitmap
snapshotByRecyclerView(final RecyclerView recyclerView
, final int spacing
) {
return snapshotByRecyclerView(recyclerView
, BITMAP_CONFIG
, spacing
, spacing
);
}
public static Bitmap
snapshotByRecyclerView(final RecyclerView recyclerView
,
final Bitmap
.Config config
, final int spacing
) {
return snapshotByRecyclerView(recyclerView
, config
, spacing
, spacing
);
}
public static Bitmap
snapshotByRecyclerView(final RecyclerView recyclerView
, final Bitmap
.Config config
,
final int verticalSpacing
, final int horizontalSpacing
) {
if (recyclerView
== null
|| config
== null
) return null
;
try {
RecyclerView
.Adapter adapter
= recyclerView
.getAdapter();
RecyclerView
.LayoutManager layoutManager
= recyclerView
.getLayoutManager();
if (layoutManager
!= null
&& adapter
!= null
) {
if (layoutManager
instanceof GridLayoutManager) {
return snapshotByRecyclerView_GridLayoutManager(recyclerView
,
config
, verticalSpacing
, horizontalSpacing
);
} else if (layoutManager
instanceof LinearLayoutManager) {
return snapshotByRecyclerView_LinearLayoutManager(recyclerView
,
config
, verticalSpacing
, horizontalSpacing
);
} else if (layoutManager
instanceof StaggeredGridLayoutManager) {
return snapshotByRecyclerView_StaggeredGridLayoutManager(recyclerView
,
config
, verticalSpacing
, horizontalSpacing
);
}
throw new Exception(String
.format("Not Supported %s LayoutManager", layoutManager
.getClass().getSimpleName()));
} else {
throw new Exception("Adapter or LayoutManager is Null");
}
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByRecyclerView");
}
return null
;
}
private static Bitmap
snapshotByRecyclerView_GridLayoutManager(final RecyclerView recyclerView
,
final Bitmap
.Config config
,
final int verticalSpacing
,
final int horizontalSpacing
) {
try {
RecyclerView
.Adapter adapter
= recyclerView
.getAdapter();
int itemCount
= adapter
.getItemCount();
if (itemCount
== 0) return null
;
int width
= 0, height
= 0;
Bitmap
[] bitmaps
= new Bitmap[itemCount
];
GridLayoutManager gridLayoutManager
= (GridLayoutManager
) recyclerView
.getLayoutManager();
boolean vertical
= (gridLayoutManager
.getOrientation() == 1);
int spanCount
= gridLayoutManager
.getSpanCount();
int lineNumber
= getMultiple(itemCount
, spanCount
);
if (vertical
) {
int childWidth
= (recyclerView
.getWidth() - (spanCount
- 1) * horizontalSpacing
) / spanCount
;
int[] rowHeightArrays
= new int[lineNumber
];
int tempHeight
;
for (int i
= 0; i
< lineNumber
; i
++) {
tempHeight
= 0;
for (int j
= 0; j
< spanCount
; j
++) {
int position
= i
* spanCount
+ j
;
if (position
< itemCount
) {
RecyclerView
.ViewHolder holder
= adapter
.createViewHolder(recyclerView
, adapter
.getItemViewType(position
));
adapter
.onBindViewHolder(holder
, position
);
View childView
= holder
.itemView
;
measureView(childView
, childWidth
);
bitmaps
[position
] = canvasBitmap(childView
, config
);
int itemHeight
= childView
.getMeasuredHeight();
tempHeight
= Math
.max(itemHeight
, tempHeight
);
}
if (j
== spanCount
- 1) {
height
+= tempHeight
;
rowHeightArrays
[i
] = tempHeight
;
}
}
}
height
+= (verticalSpacing
* (lineNumber
- 1));
width
= recyclerView
.getMeasuredWidth();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendHeight
= 0;
for (int i
= 0; i
< lineNumber
; i
++) {
int rowHeight
= rowHeightArrays
[i
];
for (int j
= 0; j
< spanCount
; j
++) {
int position
= i
* spanCount
+ j
;
if (position
< itemCount
) {
Bitmap bmp
= bitmaps
[position
];
int left
= j
* (horizontalSpacing
+ childWidth
);
Matrix matrix
= new Matrix();
matrix
.postTranslate(left
, appendHeight
);
canvas
.drawBitmap(bmp
, matrix
, PAINT
);
bmp
.recycle();
bmp
= null
;
}
if (j
== spanCount
- 1) {
appendHeight
+= (rowHeight
+ verticalSpacing
);
}
}
}
return bitmap
;
} else {
lineNumber
= Math
.min(spanCount
, itemCount
);
int[] rowWidthArrays
= new int[lineNumber
];
int[] rowHeightArrays
= new int[lineNumber
];
int numColumns
= getMultiple(itemCount
, lineNumber
);
int tempHeight
;
for (int i
= 0; i
< lineNumber
; i
++) {
tempHeight
= 0;
for (int j
= 0; j
< numColumns
; j
++) {
int position
= j
* lineNumber
+ i
;
if (position
< itemCount
) {
RecyclerView
.ViewHolder holder
= adapter
.createViewHolder(recyclerView
, adapter
.getItemViewType(position
));
adapter
.onBindViewHolder(holder
, position
);
View childView
= holder
.itemView
;
measureView(childView
, 0);
bitmaps
[position
] = canvasBitmap(childView
, config
);
rowWidthArrays
[i
] += childView
.getMeasuredWidth();
int itemHeight
= childView
.getMeasuredHeight();
tempHeight
= Math
.max(itemHeight
, tempHeight
);
}
if (j
== numColumns
- 1) {
height
+= tempHeight
;
width
= Math
.max(width
, rowWidthArrays
[i
]);
rowHeightArrays
[i
] = tempHeight
;
}
}
}
height
+= (verticalSpacing
* (lineNumber
- 1));
width
+= (horizontalSpacing
* (numColumns
- 1));
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendWidth
= 0, appendHeight
= 0;
for (int i
= 0; i
< lineNumber
; i
++) {
int rowHeight
= rowHeightArrays
[i
];
for (int j
= 0; j
< numColumns
; j
++) {
int position
= j
* lineNumber
+ i
;
if (position
< itemCount
) {
Bitmap bmp
= bitmaps
[position
];
int left
= appendWidth
+ (j
* horizontalSpacing
);
Matrix matrix
= new Matrix();
matrix
.postTranslate(left
, appendHeight
);
canvas
.drawBitmap(bmp
, matrix
, PAINT
);
appendWidth
+= bmp
.getWidth();
bmp
.recycle();
bmp
= null
;
}
if (j
== numColumns
- 1) {
appendWidth
= 0;
appendHeight
+= (rowHeight
+ verticalSpacing
);
}
}
}
return bitmap
;
}
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByRecyclerView_GridLayoutManager");
}
return null
;
}
private static Bitmap
snapshotByRecyclerView_LinearLayoutManager(final RecyclerView recyclerView
,
final Bitmap
.Config config
,
final int verticalSpacing
,
final int horizontalSpacing
) {
try {
RecyclerView
.Adapter adapter
= recyclerView
.getAdapter();
int itemCount
= adapter
.getItemCount();
if (itemCount
== 0) return null
;
int width
= 0, height
= 0;
Bitmap
[] bitmaps
= new Bitmap[itemCount
];
LinearLayoutManager linearLayoutManager
= (LinearLayoutManager
) recyclerView
.getLayoutManager();
boolean vertical
= (linearLayoutManager
.getOrientation() == 1);
if (vertical
) {
for (int i
= 0; i
< itemCount
; i
++) {
RecyclerView
.ViewHolder holder
= adapter
.createViewHolder(recyclerView
, adapter
.getItemViewType(i
));
adapter
.onBindViewHolder(holder
, i
);
View childView
= holder
.itemView
;
measureView(childView
, recyclerView
.getWidth());
bitmaps
[i
] = canvasBitmap(childView
, config
);
height
+= childView
.getMeasuredHeight();
}
height
+= (verticalSpacing
* (itemCount
- 1));
width
= recyclerView
.getMeasuredWidth();
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendHeight
= 0;
for (int i
= 0; i
< itemCount
; i
++) {
Bitmap bmp
= bitmaps
[i
];
canvas
.drawBitmap(bmp
, 0, appendHeight
, PAINT
);
appendHeight
+= (bmp
.getHeight() + verticalSpacing
);
bmp
.recycle();
bmp
= null
;
}
return bitmap
;
} else {
int tempHeight
= 0;
for (int i
= 0; i
< itemCount
; i
++) {
RecyclerView
.ViewHolder holder
= adapter
.createViewHolder(recyclerView
, adapter
.getItemViewType(i
));
adapter
.onBindViewHolder(holder
, i
);
View childView
= holder
.itemView
;
measureView(childView
, 0);
bitmaps
[i
] = canvasBitmap(childView
, config
);
width
+= childView
.getMeasuredWidth();
int itemHeight
= childView
.getMeasuredHeight();
tempHeight
= Math
.max(itemHeight
, tempHeight
);
}
width
+= (horizontalSpacing
* (itemCount
- 1));
height
= tempHeight
;
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
int appendWidth
= 0;
for (int i
= 0; i
< itemCount
; i
++) {
Bitmap bmp
= bitmaps
[i
];
canvas
.drawBitmap(bmp
, appendWidth
, 0, PAINT
);
appendWidth
+= (bmp
.getWidth() + horizontalSpacing
);
bmp
.recycle();
bmp
= null
;
}
return bitmap
;
}
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByRecyclerView_LinearLayoutManager");
}
return null
;
}
private static Bitmap
snapshotByRecyclerView_StaggeredGridLayoutManager(final RecyclerView recyclerView
,
final Bitmap
.Config config
,
final int verticalSpacing
,
final int horizontalSpacing
) {
try {
RecyclerView
.Adapter adapter
= recyclerView
.getAdapter();
int itemCount
= adapter
.getItemCount();
if (itemCount
== 0) return null
;
int width
= 0, height
= 0;
Bitmap
[] bitmaps
= new Bitmap[itemCount
];
StaggeredGridLayoutManager staggeredGridLayoutManager
= (StaggeredGridLayoutManager
) recyclerView
.getLayoutManager();
boolean vertical
= (staggeredGridLayoutManager
.getOrientation() == 1);
int spanCount
= staggeredGridLayoutManager
.getSpanCount();
int lineNumber
= getMultiple(itemCount
, spanCount
);
if (vertical
) {
int childWidth
= (recyclerView
.getWidth() - (spanCount
- 1) * horizontalSpacing
) / spanCount
;
int[] itemHeightArrays
= new int[itemCount
];
for (int i
= 0; i
< itemCount
; i
++) {
RecyclerView
.ViewHolder holder
= adapter
.createViewHolder(recyclerView
, adapter
.getItemViewType(i
));
adapter
.onBindViewHolder(holder
, i
);
View childView
= holder
.itemView
;
measureView(childView
, childWidth
);
bitmaps
[i
] = canvasBitmap(childView
, config
);
itemHeightArrays
[i
] = childView
.getMeasuredHeight();
}
int[] columnsItemNumberArrays
= new int[spanCount
];
int[] columnsHeightArrays
= new int[spanCount
];
for (int i
= 0; i
< itemCount
; i
++) {
int minIndex
= getMinimumIndex(columnsHeightArrays
);
columnsHeightArrays
[minIndex
] += itemHeightArrays
[i
];
columnsItemNumberArrays
[minIndex
] += 1;
}
if (lineNumber
>= 2) {
for (int i
= 0; i
< spanCount
; i
++) {
columnsHeightArrays
[i
] += (columnsItemNumberArrays
[i
] - 1) * verticalSpacing
;
}
}
int columnsHeightMaxIndex
= getMaximumIndex(columnsHeightArrays
);
int maxColumnsHeight
= columnsHeightArrays
[columnsHeightMaxIndex
];
height
= maxColumnsHeight
;
width
= recyclerView
.getMeasuredWidth();
columnsHeightArrays
= new int[spanCount
];
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
for (int i
= 0; i
< itemCount
; i
++) {
int minIndex
= getMinimumIndex(columnsHeightArrays
);
int left
= minIndex
* (horizontalSpacing
+ childWidth
);
Matrix matrix
= new Matrix();
matrix
.postTranslate(left
, columnsHeightArrays
[minIndex
]);
Bitmap bmp
= bitmaps
[i
];
canvas
.drawBitmap(bmp
, matrix
, PAINT
);
columnsHeightArrays
[minIndex
] += (itemHeightArrays
[i
] + verticalSpacing
);
bmp
.recycle();
bmp
= null
;
}
return bitmap
;
} else {
lineNumber
= Math
.min(spanCount
, itemCount
);
int[] itemWidthArrays
= new int[itemCount
];
int[] itemHeightArrays
= new int[itemCount
];
for (int i
= 0; i
< itemCount
; i
++) {
RecyclerView
.ViewHolder holder
= adapter
.createViewHolder(recyclerView
, adapter
.getItemViewType(i
));
adapter
.onBindViewHolder(holder
, i
);
View childView
= holder
.itemView
;
measureView(childView
, 0);
bitmaps
[i
] = canvasBitmap(childView
, config
);
itemWidthArrays
[i
] = childView
.getMeasuredWidth();
itemHeightArrays
[i
] = childView
.getMeasuredHeight();
}
int[] columnsTopArrays
= new int[lineNumber
];
int[] columnsItemNumberArrays
= new int[lineNumber
];
int[] columnsWidthArrays
= new int[lineNumber
];
int[] columnsHeightArrays
= new int[lineNumber
];
for (int i
= 0; i
< itemCount
; i
++) {
int minIndex
= getMinimumIndex(columnsWidthArrays
);
columnsWidthArrays
[minIndex
] += itemWidthArrays
[i
];
columnsItemNumberArrays
[minIndex
] += 1;
columnsHeightArrays
[minIndex
] = Math
.max(itemHeightArrays
[i
], columnsHeightArrays
[minIndex
]);
}
for (int i
= 0; i
< lineNumber
; i
++) {
if (columnsItemNumberArrays
[i
] > 1) {
columnsWidthArrays
[i
] += (columnsItemNumberArrays
[i
] - 1) * horizontalSpacing
;
}
if (i
> 0) {
columnsTopArrays
[i
] = height
+ (i
* verticalSpacing
);
}
height
+= columnsHeightArrays
[i
];
}
int maxColumnsWidth
= columnsWidthArrays
[getMaximumIndex(columnsWidthArrays
)];
height
+= (lineNumber
- 1) * verticalSpacing
;
width
= maxColumnsWidth
;
columnsWidthArrays
= new int[lineNumber
];
Bitmap bitmap
= Bitmap
.createBitmap(width
, height
, config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
for (int i
= 0; i
< itemCount
; i
++) {
int minIndex
= getMinimumIndex(columnsWidthArrays
);
Matrix matrix
= new Matrix();
matrix
.postTranslate(columnsWidthArrays
[minIndex
], columnsTopArrays
[minIndex
]);
Bitmap bmp
= bitmaps
[i
];
canvas
.drawBitmap(bmp
, matrix
, PAINT
);
columnsWidthArrays
[minIndex
] += (itemWidthArrays
[i
] + horizontalSpacing
);
bmp
.recycle();
bmp
= null
;
}
return bitmap
;
}
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "snapshotByRecyclerView_StaggeredGridLayoutManager");
}
return null
;
}
private static Bitmap
canvasBitmap(final View childView
, final Bitmap
.Config config
) {
Bitmap bitmap
= Bitmap
.createBitmap(childView
.getMeasuredWidth(), childView
.getMeasuredHeight(), config
);
Canvas canvas
= new Canvas(bitmap
);
canvas
.drawColor(BACKGROUND_COLOR
);
childView
.draw(canvas
);
return bitmap
;
}
private static int[] getScreenWidthHeight() {
try {
WindowManager windowManager
= (WindowManager
) DevUtils
.getContext().getSystemService(Context
.WINDOW_SERVICE
);
if (windowManager
== null
) {
DisplayMetrics displayMetrics
= DevUtils
.getContext().getResources().getDisplayMetrics();
return new int[]{displayMetrics
.widthPixels
, displayMetrics
.heightPixels
};
}
Point point
= new Point();
if (Build
.VERSION
.SDK_INT
>= Build
.VERSION_CODES
.JELLY_BEAN_MR1
) {
windowManager
.getDefaultDisplay().getRealSize(point
);
} else {
windowManager
.getDefaultDisplay().getSize(point
);
}
return new int[]{point
.x
, point
.y
};
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "getScreenWidthHeight");
}
return new int[]{0, 0};
}
private static int getStatusBarHeight(final Activity activity
) {
try {
Rect rect
= new Rect();
activity
.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect
);
return rect
.top
;
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "getStatusBarHeight");
}
return 0;
}
private static int getMultiple(final int value
, final int divisor
) {
if (value
<= 0 || divisor
<= 0) return 0;
if (value
<= divisor
) return 1;
return (value
% divisor
== 0) ? (value
/ divisor
) : (value
/ divisor
) + 1;
}
private static int getMinimumIndex(final int[] data
) {
if (data
!= null
) {
int len
= data
.length
;
if (len
> 0) {
int index
= 0;
int temp
= data
[index
];
for (int i
= 1; i
< len
; i
++) {
int value
= data
[i
];
if (value
< temp
) {
index
= i
;
temp
= value
;
}
}
return index
;
}
}
return -1;
}
private static int getMaximumIndex(final int[] data
) {
if (data
!= null
) {
int len
= data
.length
;
if (len
> 0) {
int index
= 0;
int temp
= data
[index
];
for (int i
= 1; i
< len
; i
++) {
int value
= data
[i
];
if (value
> temp
) {
index
= i
;
temp
= value
;
}
}
return index
;
}
}
return -1;
}
private static void measureView(final View view
, final int specifiedWidth
) {
measureView(view
, specifiedWidth
, 0);
}
private static void measureView(final View view
, final int specifiedWidth
, final int specifiedHeight
) {
try {
ViewGroup
.LayoutParams layoutParams
= view
.getLayoutParams();
int widthMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(0, View
.MeasureSpec
.UNSPECIFIED
);
int heightMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(0, View
.MeasureSpec
.UNSPECIFIED
);
if (specifiedWidth
> 0) {
widthMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(specifiedWidth
, View
.MeasureSpec
.EXACTLY
);
}
if (specifiedHeight
> 0) {
heightMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(specifiedHeight
, View
.MeasureSpec
.EXACTLY
);
}
if (layoutParams
!= null
) {
int width
= layoutParams
.width
;
int height
= layoutParams
.height
;
if (width
> 0 && height
> 0) {
widthMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(width
, View
.MeasureSpec
.EXACTLY
);
heightMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(height
, View
.MeasureSpec
.EXACTLY
);
} else if (width
> 0) {
widthMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(width
, View
.MeasureSpec
.EXACTLY
);
} else if (height
> 0) {
heightMeasureSpec
= View
.MeasureSpec
.makeMeasureSpec(height
, View
.MeasureSpec
.EXACTLY
);
}
}
view
.measure(widthMeasureSpec
, heightMeasureSpec
);
view
.layout(0, 0, view
.getMeasuredWidth(), view
.getMeasuredHeight());
} catch (Exception e
) {
LogPrintUtils
.eTag(TAG
, e
, "measureView");
}
}
}