700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android截屏-- ScrollView ListView及RecyclerView截屏(三)

Android截屏-- ScrollView ListView及RecyclerView截屏(三)

时间:2024-05-27 15:42:47

相关推荐

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)`来完成截图,

/*** /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。

/*** /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上看到的方案。

/*** /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]

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。