界面的布局情况:
功能要求:实现全屏幕的截图功能,包括ListView中滑动出现的内容。
实现思路:由于ListView容器为了能加载大数量的Item,内部已经实现了对不可视资源的回收机制(详细可以参考: ),如果直接调用getChild的方式,会导致不可见的部分无法获取;因此,只能通过ListAdapter的getView来获取,然后调用每个item view的绘制过程,生成相关的图片,然后再拼起来,大概实现思路就是这样。
这里首先要解决的一个问题是:如何把View转化成图片?
我在这里参考了这篇文章:
我使用了第二种方案有效,其思路也就是View的绘制流程 measure -> layout -> draw。
ListView 的Item布局:
我们想要的是:
但是可能会变成:
原因大概是由于调用getView返回的View一般都是通过View.inflate得到的,因此在measure的过程中没有上一层父容器的尺寸参考,所以在传入measure参数为:
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
的时候,就会只能刚好装下里面的View,因此看起来变短了。
我们可以这样子修改,指定View的宽度或者高度,在这里,我需要指定它的宽度(width是屏幕宽度):
view.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
好了,ListView的截图代码看起来大概就像这样子:
public static Bitmap createBitmap(ListView listView){ int titleHeight,width, height, rootHeight=0; Bitmap bitmap; Canvas canvas; int yPos; int listItemNum; ListchildViews = null; width = getScreenWidth();//宽度等于屏幕宽 ListAdapter listAdapter = listView.getAdapter(); listItemNum = listAdapter.getCount()> childViews = new ArrayList (listItemNum); View itemView; //计算整体高度: for(int pos=0; pos < listItemNum; ++pos){ itemView = listAdapter.getView(pos, null, rootView); //measure过程 itemView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); childViews.add(itemView); rootHeight += itemView.getMeasuredHeight(); } height = rootHeight; bitmap = BitmapUtil.createBitmap(width, height, Config.ARGB_8888); canvas = new Canvas(bitmap); Bitmap itemBitmap; View itemView; int childHeight; //把每个ItemView生成图片,并画到背景画布上 for(int pos=0; pos < childViews.size(); ++pos){ itemView = childViews.get(pos); childHeight = itemView.getMeasuredHeight(); itemBitmap = viewToBitmap(itemView,width,childHeight); if(itemBitmap!=null){ canvas.drawBitmap(itemBitmap, 0, yPos, null); } yPos = childHeight +yPos; } canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); return bitmap;}private static Bitmap viewToBitmap(View view,int viewWidth, int viewHeight){ view.layout(0, 0, viewWidth, viewHeight); view.buildDrawingCache(); Bitmap bitmap = view.getDrawingCache(); return bitmap;}
到这里就完了么?可能还没有。。。笔者就碰到了这种情况:Item的部分内容没有画出来...
正确:
错误:
既然有的出来了,有的没出来,羊毛肯定就出在羊身上了...
具体原因我也暂时没有分析,把代码贴出来给大家做参考吧:
正确布局代码:
失败的布局代码:
最后分享一张成功截图全貌:
原文: