Android截屏-- ScrollView,ListView及RecyclerView截屏(三)
在做分享功能的时候,需要截取全屏内容,一屏展示不完的内容,一般我们会用到 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截屏(三)相关推荐
- Android滚动截屏,ScrollView截屏,Listview截屏,Recyclerview截屏, 截长图
最近在做一个关于截频的功能, 恰逢鸿洋大神分享了一篇相关的博客, 我使用之后觉得甚是好用, 所以也整理了一下,以供学习. 在做分享功能的时候,需要截取全屏内容还有截长图,一屏展示不完的内容,一般我们会 ...
- 【Android】ListView、RecyclerView、ScrollView里嵌套ListView 相对优雅的解决方案:NestFullListView
一 背景概述: ScrollView里嵌套ListView,一直是Android开发者(反正至少是我们组)最讨厌的设计之一,完美打破ListView(RecyclerView)的复用机制,成功的将Na ...
- android如何截屏快捷键是什么手机,安卓截屏快捷键是什么?截屏方法总结 - Android教程 - 安卓中文网...
现如今,使用安卓手机的机友们是越来越多,但是对于新手们来说,大家对安卓手机又有多了解呢?相信大家在使用手机的过程中一定有过这样的经历,经常聊QQ以及一些其他的聊天工具,有时微博想截个屏与大家分享都无从 ...
- android 8.1 截屏,Android8.1 MTK平台 截屏功能分析
前言 涉及到的源码有 frameworksbaseservicescorejavacomandroidserverpolicyPhoneWindowManager.java vendormediate ...
- 2022-10-09 Android app禁止截屏方法 和 在禁止截屏的情况下录制屏幕
一.APP有时候为了保护用户的隐私安全会禁止用户录屏和截屏,比如金融类的app等.可以在app的onCreate方法中添加这么一段代码 1.代码 //禁止app录屏和截屏getWindow().set ...
- android获取状态栏截屏按钮状态,关于代码截屏带状态栏的问题
昨天产品经理告诉我,希望能实现仿网易严选那样,可以捕捉到用户的截屏操作,然后进行截屏分享的小功能. 在实现的过程中遇到的最大问题就是截屏为什么没有状态栏???然后各种查找,资料聊聊无几,只有大神Ope ...
- 三星 android截屏快捷键是什么手机,截屏的快捷键是什么,手把手教你三星手机怎么截屏...
大家平时在玩手机的时候,难免有需要截图截屏的时候.当前的手机都有截图功能,也有相应的截图快捷键.对于一些不熟悉三星手机操作的小伙伴而言,可能不知道应该怎么截图,下面,小编给大家带来了三星手机的截图流程 ...
- 华为android截屏快捷键,华为手机四大截屏方法,你会用几个?
原标题:华为手机四大截屏方法,你会用几个? 1.智灵截屏 先设置智灵相关操作为"截屏",操作路径:"设置">>"智能辅助"> ...
- android悬浮球截屏,ColorOS7的悬浮球截屏和长截屏怎么用,有哪些方式
11月20日OPPO官方发布了这个全新的ColorOS 7系统了,在发布会上展现了很多惊艳的功能,但是对于操作便捷来说,我最喜欢的还是截屏方式的改变,变得花样更多了,相信这个截屏在大家使用手机的过程中 ...
最新文章
- 目录忽略_宣传册设计中目录的构思方法和运用
- linux c atoi strtol 区别
- Ubuntu中安装最新Docker社区版
- 一个成功敏捷团队的失败历程
- Asp.net細微的效率提升
- Linux解决find /run/user/1000/gvfs
- 2019 年百度之星·程序设计大赛 - 初赛一
- environment variable
- vue中使用cookies和crypto-js实现记住密码和加密
- vue-cli设置跨域代理 + 开发/生成环境简单请求接口设置
- vue 事件上加阻止冒泡 阻止默认事件
- 决策树_预测泰坦尼可号幸存者
- Linux 杀死进程方法大全(kill,killall)
- matlab导出高分辨率图片,Matlab导出高DPI图像——生成高分辨率.eps .tiff .jpg
- VS Code Css格式化插件
- Echarts title和subtitle进行合并显示
- Gulp老矣 尚能饭否
- docker centos + pbx
- java设计模式 (二) 创建模式
- java高并发编程--03--线程间通信
热门文章
- 中国旅游的十大趋势2
- 双因素认证的解决方案
- 【2023 · CANN训练营第一季】初识新一代开发者套件 Atlas 200I DK A2---介绍Atlas 200I DK A2的基本使用
- Linux+Docker安装Nacos并使用Mysql持久化,附安装参数说明
- 期待筷子兄弟“小苹果”的背后
- 2020牛客寒假算法基础集训营5:B.牛牛战队的比赛地(二分/三分)
- kotlin flowlayout
- 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
- 浙江大学计算机专业招高考日语吗,高考日语可以报哪些学校和专业
- 关于酷狗的动态壁纸的代码(罗马时钟)