Android滚动截屏,ScrollView截屏
在做分享功能的时候,需要截取全屏内容,一屏展示不完的内容,一般我们会用到 ListView ,ScrollView或Recyclerview
一: 普通截屏的实现
获取当前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(), , , 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 >= ) {
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(, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(, MeasureSpec.UNSPECIFIED));
v.layout(, , v.getMeasuredWidth(), v.getMeasuredHeight());
}
Bitmap b = Bitmap.createBitmap(v.getDrawingCache(), , , 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 = ;
Bitmap bitmap = null;
for (int i = ; 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 = ;
List<Bitmap> bmps = new ArrayList<Bitmap>(); for (int i = ; i < itemscount; i++) { View childView = adapter.getView(i, null, listview);
childView.measure(
View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(, View.MeasureSpec.UNSPECIFIED)); childView.layout(, , 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 = ; for (int i = ; i < bmps.size(); i++) {
Bitmap bmp = bmps.get(i);
bigcanvas.drawBitmap(bmp, , 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 = ;
Paint paint = new Paint();
int iHeight = ;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / ); // Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / ;
LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);
for (int i = ; 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(, View.MeasureSpec.UNSPECIFIED));
holder.itemView.layout(, , 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 = ; 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 = -;
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 > ? activity.getResources().getDimensionPixelSize(resourceId) : ;
}
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 = ;
if (Build.VERSION.SDK_INT > ) {
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 = ;
if (Build.VERSION.SDK_INT > ) {
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;
}
相关源码:
Android滚动截屏,ScrollView截屏的更多相关文章
- android 滚动视图(ScrollView)
为了可以让内嵌布局管理器之中加入多个显示的组件,而且又保证程序不这么冗余,所以可以通过 Activity程序进行控制,向内嵌布局管理器中添加多个组件. ScrollView提供一个显示的容器,可以包含 ...
- Android长截屏-- ScrollView,ListView及RecyclerView截屏
http://blog.csdn.net/wbwjx/article/details/46674157 Android长截屏-- ScrollView,ListView及RecyclerV ...
- Android 禁止截屏、录屏 — 解决PopupWindow无法禁止录屏问题
项目开发中,为了用户信息的安全,会有禁止页面被截屏.录屏的需求. 这类资料,在网上有很多,一般都是通过设置Activity的Flag解决,如: //禁止页面被截屏.录屏 getWindow().add ...
- 搭建前端监控系统(六)JS截屏和录屏篇
怎样定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一系列操作之后.错误的原因可能源于机型,网络环境,接口请求,复杂的操作行为等等,在我们想要去解决的时候很难复现出来,自然也就无法解决 ...
- Chrome截图截满滑动栏,QQ截长屏,录屏
1.Chrome截图截满滑动栏 一般我们截图都是用QQ的Ctrl+shift+A,但是网页不好截,这里我们可以用Chrome控制台来截全网页: F12或Ctrl+shift+i打开控制台: 点击一下控 ...
- Android -- 距离感应器控制屏幕灭屏白屏
权限 <u ...
- (转)android中利用 ViewPage 实现滑动屏
最近实现了这样的一个效果:滑动界面出现拖拽效果,可翻动3屏,也可点击按钮翻动页面. 主要利用android.support.v4.view.ViewPager控件来实现. 第一个界面: 滑动屏幕: 换 ...
- jquery 单行滚动、批量多行滚动、文字图片翻屏滚动效果代码
jquery单行滚动.批量多行滚动.文字图片翻屏滚动效果代码,需要的朋友可以参考下. 以下代码,运行后,需要刷新下,才能加载jquery,要不然看不到效果.一.单行滚动效果 <!DOCTYPE ...
- Android 设置ListView不可滚动 及在ScrollView中不可滚动的设置
http://m.blog.csdn.net/blog/yusewuhen/43706169 转载请注明出处: http://blog.csdn.net/androiddevelop/article/ ...
随机推荐
- php之购物车类思路及代码
<?php /* 购物车类 1.整站范围内,购物车--全局有效 解决:把购物车的信息,放在session里 2.既然全局有效,购物车的实例只有一个 解决:单例模式 技术选型:session+单例 ...
- 51中的C语言数据类型
在标准C语言中基本的数据类型为char,int,short,long,float 和double,而在C51编译器中int和short相同,float和double相同. 说明: (1)类型修饰符si ...
- Django Web在Apache上的部署
1. 安装配置Apache 2. 安装wsgi_mod模块 3. 开放相应端口 vim /etc/sysconfig/iptables # Firewall configuration written ...
- SVN 使用的简单整理
1. 在SVN服务器上创建存储Dir,并和个人主机建立联系. 现在SVN服务器上创建一个存储文件夹svn_storeDir.然后在个人电脑上建立一个本地文件夹local_Dir. 进入 ...
- Swift中KIF测试的特点-b
我最近在忙着回归到过去测试代码的老路子,使用KIF和XCTest框架,这样会使得iOS中的测试变得简单.当我开始捣鼓KIF的时候,我用Swift写的应用出了点小问题,不过最终还是很机智的搞定了.在我写 ...
- Oracle问题解决(sqlplus无法登陆)
命令行 sqlplus 无法登陆,常常是用户名/密码错误.监听配置错误或未启动.数据库服务名丢失等等原因. 用户名/密码错误 找到自己设的密码 这全靠自己创建数据库实例时,备份或记住相关信息 若最后没 ...
- 应用SecureCRT(发送接收文件)
使用 SecureCRT 和 cz. sz,可以从 Linux 服务器上下载/上传文件. Linux 上要安装 lszrz 包 (1)编译安装root 账号登陆后,依次执行以下命令 cd /tmp w ...
- N.O.W,O.R,N.E.V.E.R--12days to LNOI2015
双向链表 单调队列,双端队列 单调栈 堆 带权并查集 hash 表 双hash 树状数组 线段树合并 平衡树 Treap 随机平衡二叉树 Scapegoat Tree 替罪羊树 朝鲜树 块状数组,块状 ...
- hadoop 2.2.0 集群部署 坑
注意fs.defaultFS为2..0新的变量,代替旧的:fs.default.name hadoop 2.2.0 集群启动命令:bin/hdfs namenode -formatsbin/start ...
- JSP session 获取id和session持续时间
<%@ page contentType="text/html;charset=utf-8" pageEncoding="utf-8"%> < ...