在做分享功能的时候,需要截取全屏内容,一屏展示不完的内容,一般我们会用到 ListView 或 ScrollView

一: 普通截屏的实现

获取当前Window 的 DrawingCache 的方式,即decorView的DrawingCache

  /*** shot the current screen ,with the status but the status is trans *** @param ctx current activity*/public static Bitmap shotActivity(Activity ctx) {View view = ctx.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bp = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, view.getMeasuredWidth(),view.getMeasuredHeight());view.setDrawingCacheEnabled(false);view.destroyDrawingCache();return bp;}

获取当前View的DrawingCache:

   public static Bitmap getViewBp(View v) {if (null == v) {return null;}v.setDrawingCacheEnabled(true);v.buildDrawingCache();if (Build.VERSION.SDK_INT >= 11) {v.measure(MeasureSpec.makeMeasureSpec(v.getWidth(),MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(v.getHeight(), MeasureSpec.EXACTLY));v.layout((int) v.getX(), (int) v.getY(),(int) v.getX() + v.getMeasuredWidth(),(int) v.getY() + v.getMeasuredHeight());} else {v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());}Bitmap b = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());v.setDrawingCacheEnabled(false);v.destroyDrawingCache();return b;}

二:开源方案

在滚动视图中,如果当前View并没有在视图中全部绘制出来,我们可以利用View的ScrollTo()和ScrollBy()方法来移动画布,同时获取当前View的可视部分的DrawingCache,最后进行拼接得到其Bitmap,参考:PGSSoft/scrollscreenshot@[Github],原理图如下:

三: ScrollView截屏

三个截屏中,ScrollView最简单,因为ScrollView只有一个childView,虽然没有全部显示在界面上,但是已经全部渲染绘制,因此可以直接 调用`scrollView.draw(canvas)`来完成截图,

  /*** http://blog.csdn.net/lyy1104/article/details/40048329*/public static Bitmap shotScrollView(ScrollView scrollView) {int h = 0;Bitmap bitmap = null;for (int i = 0; i < scrollView.getChildCount(); i++) {h += scrollView.getChildAt(i).getHeight();scrollView.getChildAt(i).setBackgroundColor(Color.parseColor("#ffffff"));}bitmap = Bitmap.createBitmap(scrollView.getWidth(), h, Bitmap.Config.RGB_565);final Canvas canvas = new Canvas(bitmap);scrollView.draw(canvas);return bitmap;}

四: ListView截屏

而ListView就是会回收与重用Item,并且只会绘制在屏幕上显示的ItemView,根据stackoverflow上大神的建议,采用一个List来存储Item的视图,这种方案依然不够好,当Item足够多的时候,可能会发生oom。

  /*** http://stackoverflow.com/questions/12742343/android-get-screenshot-of-all-listview-items*/public static Bitmap shotListView(ListView listview) {ListAdapter adapter = listview.getAdapter();int itemscount = adapter.getCount();int allitemsheight = 0;List<Bitmap> bmps = new ArrayList<Bitmap>();for (int i = 0; i < itemscount; i++) {View childView = adapter.getView(i, null, listview);childView.measure(View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());childView.setDrawingCacheEnabled(true);childView.buildDrawingCache();bmps.add(childView.getDrawingCache());allitemsheight += childView.getMeasuredHeight();}Bitmap bigbitmap =Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight, Bitmap.Config.ARGB_8888);Canvas bigcanvas = new Canvas(bigbitmap);Paint paint = new Paint();int iHeight = 0;for (int i = 0; i < bmps.size(); i++) {Bitmap bmp = bmps.get(i);bigcanvas.drawBitmap(bmp, 0, iHeight, paint);iHeight += bmp.getHeight();bmp.recycle();bmp = null;}return bigbitmap;}

五: RecyclerView截屏

我们都知道,在新的Android版本中,已经可以用RecyclerView来代替使用ListView的场景,相比较ListView,RecyclerView对Item View的缓存支持的更好。可以采用和ListView相同的方案,这里也是在stackoverflow上看到的方案。

/*** https://gist.github.com/PrashamTrivedi/809d2541776c8c141d9a*/public static Bitmap shotRecyclerView(RecyclerView view) {RecyclerView.Adapter adapter = view.getAdapter();Bitmap bigBitmap = null;if (adapter != null) {int size = adapter.getItemCount();int height = 0;Paint paint = new Paint();int iHeight = 0;final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);// Use 1/8th of the available memory for this memory cache.final int cacheSize = maxMemory / 8;LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);for (int i = 0; i < size; i++) {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) {bitmaCache.put(String.valueOf(i), drawingCache);}height += holder.itemView.getMeasuredHeight();}bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);Canvas bigCanvas = new Canvas(bigBitmap);Drawable lBackground = view.getBackground();if (lBackground instanceof ColorDrawable) {ColorDrawable lColorDrawable = (ColorDrawable) lBackground;int lColor = lColorDrawable.getColor();bigCanvas.drawColor(lColor);}for (int i = 0; i < size; i++) {Bitmap bitmap = bitmaCache.get(String.valueOf(i));bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);iHeight += bitmap.getHeight();bitmap.recycle();}}return bigBitmap;}

六: 其他屏幕相关工具

1.获取状态来高度常见方式

    /*** get the height of status **/public static int getStatusH(Activity ctx) {Rect s = new Rect();ctx.getWindow().getDecorView().getWindowVisibleDisplayFrame(s);return s.top;}
    /*** get the height of status **/public static int getStatusH(Context ctx) {int statusHeight = -1;try {Class<?> clazz = Class.forName("com.android.internal.R$dimen");Object object = clazz.newInstance();int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());statusHeight = ctx.getResources().getDimensionPixelSize(height);} catch (Exception e) {e.printStackTrace();}return statusHeight;}
    /*** get the height of status **/public static int getStatusHeight(Activity activity) {int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");return resourceId > 0 ? activity.getResources().getDimensionPixelSize(resourceId) : 0;}

2.获取标题栏高度

    /*** get the height of title **/public static int getTitleH(Activity ctx) {int contentTop = ctx.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();return contentTop - getStatusH(ctx);}

3.获取屏幕宽高

    /*** get the width of screen ***/public static int getScreenW(Context ctx) {int w = 0;if (Build.VERSION.SDK_INT > 13) {Point p = new Point();((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(p);w = p.x;} else {w = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();}return w;}
    /*** get the height of screen **/public static int getScreenH(Context ctx) {int h = 0;if (Build.VERSION.SDK_INT > 13) {Point p = new Point();((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(p);h = p.y;} else {h = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight();}return h;}
    /*** 获得屏幕高度** @param context* @return*/public static int getScreenWidth(Context context) {WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.widthPixels;}

相关源码:

ScreenUtil@[Github]

Android截屏-- ScrollView,ListView及RecyclerView截屏(三)相关推荐

  1. Android滚动截屏,ScrollView截屏,Listview截屏,Recyclerview截屏, 截长图

    最近在做一个关于截频的功能, 恰逢鸿洋大神分享了一篇相关的博客, 我使用之后觉得甚是好用, 所以也整理了一下,以供学习. 在做分享功能的时候,需要截取全屏内容还有截长图,一屏展示不完的内容,一般我们会 ...

  2. 【Android】ListView、RecyclerView、ScrollView里嵌套ListView 相对优雅的解决方案:NestFullListView

    一 背景概述: ScrollView里嵌套ListView,一直是Android开发者(反正至少是我们组)最讨厌的设计之一,完美打破ListView(RecyclerView)的复用机制,成功的将Na ...

  3. android如何截屏快捷键是什么手机,安卓截屏快捷键是什么?截屏方法总结 - Android教程 - 安卓中文网...

    现如今,使用安卓手机的机友们是越来越多,但是对于新手们来说,大家对安卓手机又有多了解呢?相信大家在使用手机的过程中一定有过这样的经历,经常聊QQ以及一些其他的聊天工具,有时微博想截个屏与大家分享都无从 ...

  4. android 8.1 截屏,Android8.1 MTK平台 截屏功能分析

    前言 涉及到的源码有 frameworksbaseservicescorejavacomandroidserverpolicyPhoneWindowManager.java vendormediate ...

  5. 2022-10-09 Android app禁止截屏方法 和 在禁止截屏的情况下录制屏幕

    一.APP有时候为了保护用户的隐私安全会禁止用户录屏和截屏,比如金融类的app等.可以在app的onCreate方法中添加这么一段代码 1.代码 //禁止app录屏和截屏getWindow().set ...

  6. android获取状态栏截屏按钮状态,关于代码截屏带状态栏的问题

    昨天产品经理告诉我,希望能实现仿网易严选那样,可以捕捉到用户的截屏操作,然后进行截屏分享的小功能. 在实现的过程中遇到的最大问题就是截屏为什么没有状态栏???然后各种查找,资料聊聊无几,只有大神Ope ...

  7. 三星 android截屏快捷键是什么手机,截屏的快捷键是什么,手把手教你三星手机怎么截屏...

    大家平时在玩手机的时候,难免有需要截图截屏的时候.当前的手机都有截图功能,也有相应的截图快捷键.对于一些不熟悉三星手机操作的小伙伴而言,可能不知道应该怎么截图,下面,小编给大家带来了三星手机的截图流程 ...

  8. 华为android截屏快捷键,华为手机四大截屏方法,你会用几个?

    原标题:华为手机四大截屏方法,你会用几个? 1.智灵截屏 先设置智灵相关操作为"截屏",操作路径:"设置">>"智能辅助"> ...

  9. android悬浮球截屏,ColorOS7的悬浮球截屏和长截屏怎么用,有哪些方式

    11月20日OPPO官方发布了这个全新的ColorOS 7系统了,在发布会上展现了很多惊艳的功能,但是对于操作便捷来说,我最喜欢的还是截屏方式的改变,变得花样更多了,相信这个截屏在大家使用手机的过程中 ...

最新文章

  1. 目录忽略_宣传册设计中目录的构思方法和运用
  2. linux c atoi strtol 区别
  3. Ubuntu中安装最新Docker社区版
  4. 一个成功敏捷团队的失败历程
  5. Asp.net細微的效率提升
  6. Linux解决find /run/user/1000/gvfs
  7. 2019 年百度之星·程序设计大赛 - 初赛一
  8. environment variable
  9. vue中使用cookies和crypto-js实现记住密码和加密
  10. vue-cli设置跨域代理 + 开发/生成环境简单请求接口设置
  11. vue 事件上加阻止冒泡 阻止默认事件
  12. 决策树_预测泰坦尼可号幸存者
  13. Linux 杀死进程方法大全(kill,killall)
  14. matlab导出高分辨率图片,Matlab导出高DPI图像——生成高分辨率.eps .tiff .jpg
  15. VS Code Css格式化插件
  16. Echarts title和subtitle进行合并显示
  17. Gulp老矣 尚能饭否
  18. docker centos + pbx
  19. java设计模式 (二) 创建模式
  20. java高并发编程--03--线程间通信

热门文章

  1. 中国旅游的十大趋势2
  2. 双因素认证的解决方案
  3. 【2023 · CANN训练营第一季】初识新一代开发者套件 Atlas 200I DK A2---介绍Atlas 200I DK A2的基本使用
  4. Linux+Docker安装Nacos并使用Mysql持久化,附安装参数说明
  5. 期待筷子兄弟“小苹果”的背后
  6. 2020牛客寒假算法基础集训营5:B.牛牛战队的比赛地(二分/三分)
  7. kotlin flowlayout
  8. 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
  9. 浙江大学计算机专业招高考日语吗,高考日语可以报哪些学校和专业
  10. 关于酷狗的动态壁纸的代码(罗马时钟)