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