Android应用开发-普通View截图 RecyclerView截图 ScrollView截图分享
小标 2018-05-23 来源 : 阅读 1283 评论 0

摘要:在Android应用开发中,实际开发中经常会遇到应用内截图的相关问题,如果是普通View的话我们可以使用View的绘图缓存来获取截图,但是RecyclerView和ScrollView呢就稍微有点不同了。希望对大家学习Android应用开发有所帮助。

思路

在Android应用开发中,实际开发中经常会遇到应用内截图的相关问题,如果是普通View的话我们可以使用View的绘图缓存来获取截图,但是RecyclerView和ScrollView呢就稍微有点不同了。希望对大家学习Android应用开发有所帮助。

ScrollView还好,只有一个子View,而RecyclerView中会有itemView重用的问题,只会绘制在屏幕上显示出来的itemView,因此我们可以依次获取每个itemView的视图存储到LruCache中,最后在进行拼装。这种方案有个问题就是如果数据过多可能会产生OOM问题,不过我测试的几百条item都还好,没有遇到。

代码

普通View

普通View截图就是获取View的绘图缓存,这里的代码很简单,先看看吧:


<code><code><code> //开启绘图缓存
        view.setDrawingCacheEnabled(true);
        //这个方法可调可不调,因为在getDrawingCache()里会自动判断有没有缓存有没有准备好,
        //如果没有,会自动调用buildDrawingCache()
        view.buildDrawingCache();
        //获取绘图缓存 这里直接创建了一个新的bitmap
        //因为我们在最后需要释放缓存资源,会释放掉缓存中创建的bitmap对象
        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, view.getMeasuredWidth(),
                view.getMeasuredHeight());
        //清理绘图缓存,释放资源
        view.destroyDrawingCache();</code></code></code>

   

可以看下destroyDrawingCache()方法的源码:


<code><code><code><code>public void destroyDrawingCache() {
        if (mDrawingCache != null) {
            mDrawingCache.recycle();
            mDrawingCache = null;
        }
        if (mUnscaledDrawingCache != null) {
            mUnscaledDrawingCache.recycle();
            mUnscaledDrawingCache = null;
        }
    }</code></code></code></code>

   

如果你需要整个屏幕的截图,使用了DecorView来获取截图的话顶部会有状态栏的一条,可以通过获取状态栏高度,在重新创建Bitmap时截取掉。

RecyclerView截图

RecyclerView的截图稍微复杂些。我们可以先获取到rv的adapter对象,通过adapter对象手动调用创建和绑定ViewHolder等方法,模拟rv的加载过程,再依次保存每个itemView的绘图缓存,最后拼装成一个完整的Bitmap。看看代码吧~
1. 获取Adapter,通过Adapter获取每个itemView的绘图缓存

“` java
//获取设置的adapter
RecyclerView.Adapter adapter = view.getAdapter();
if (adapter == null) {
return null;
}
//创建保存截图的bitmap
Bitmap bigBitmap = null;
//获取item的数量
int size = adapter.getItemCount();
//recycler的完整高度 用于创建bitmap时使用
int height = 0;
//获取最大可用内存
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);


<code><code><code><code><code><code>    // 使用1/8的缓存
    final int cacheSize = maxMemory / 8;
    //把每个item的绘图缓存存储在LruCache中
    LruCache<string, bitmap=""> bitmapCache = new LruCache<>(cacheSize);
    for (int i = 0; i < size; i++) {
        //手动调用创建和绑定ViewHolder方法,
        RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));
        adapter.onBindViewHolder(holder, i);
        //测量
        holder.itemView.measure(
                View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        //布局
        holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),
                holder.itemView.getMeasuredHeight());
        //开启绘图缓存
        holder.itemView.setDrawingCacheEnabled(true);
        holder.itemView.buildDrawingCache();
        Bitmap drawingCache = holder.itemView.getDrawingCache();
        if (drawingCache != null) {
            bitmapCache.put(String.valueOf(i), drawingCache);
        }
        //获取itemView的实际高度并累加
        height += holder.itemView.getMeasuredHeight();
    }
</string,></code></code></code></code></code></code>

   


2. 创建保存截图的Bitmap 把保存的itemView绘图缓存画上去

java
//根据计算出的recyclerView高度创建bitmap
bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.RGB_565);
//创建一个canvas画板
Canvas canvas = new Canvas(bigBitmap);
//获取recyclerView的背景颜色
Drawable background = view.getBackground();
//画出recyclerView的背景色 这里只用了color一种 有需要也可以自己扩展
if (background instanceof ColorDrawable) {
ColorDrawable colorDrawable = (ColorDrawable) background;
int color = colorDrawable.getColor();
canvas.drawColor(color);
}
//当前bitmap的高度
int top = 0;
//画笔
Paint paint = new Paint();
for (int i = 0; i < size; i++) {
Bitmap bitmap = bitmapCache.get(String.valueOf(i));
canvas.drawBitmap(bitmap, 0f, top, paint);
top += bitmap.getHeight();
}

ScrollView截图

ScrollView的截图也比较简单,获取到子View的高度就好,而ScrollView只允许又一个子View。


<code><code><code><code><code><code><code> int height = 0;
        //理论上scrollView只会有一个子View啦
        for (int i = 0; i < view.getChildCount(); i++) {
            height += view.getChildAt(i).getHeight();
        }
        //创建保存缓存的bitmap
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), height, Bitmap.Config.RGB_565);
        //可以简单的把Canvas理解为一个画板 而bitmap就是块画布
        Canvas canvas = new Canvas(bitmap);
        //获取ScrollView的背景颜色
        Drawable background = view.getBackground();
        //画出ScrollView的背景色 这里只用了color一种 有需要也可以自己扩展 也可以自己直接指定一种背景色
        if (background instanceof ColorDrawable) {
            ColorDrawable colorDrawable = (ColorDrawable) background;
            int color = colorDrawable.getColor();
            canvas.drawColor(color);
        }
        //把view的内容都画到指定的画板Canvas上
        view.draw(canvas);
        return bitmap;</code></code></code></code></code></code></code>

   

关于Bitmap的recycle()方法

很多人以为这个释放资源的方法是必须调用的。其实不然,在2.3之后可以完全交由GC管理。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发Android频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved