解决Android界面中包含ListView的屏幕截图问题
来源:互联网 发布:数据库表不设置主键 编辑:程序博客网 时间:2024/06/10 05:12
转自:http://www.darcye.com/article/84263064
首先来看一下要求截图界面的布局情况:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/app_bg" android:orientation="vertical" > <include android:id="@+id/title_bar" layout="@layout/include_title_bar_no_back_btn" /> <include android:id="@+id/loading_view" layout="@layout/layout_loading" /> <ViewStub android:id="@+id/reload_viewstub" android:layout_width="match_parent" android:layout_height="match_parent" android:inflatedId="@+id/reload_view" android:layout="@layout/layout_reload" /> <LinearLayout android:id="@+id/main_view" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.gushiyingxiong.app.views.listview.PullLoadMoreListView android:id="@+id/pull_refresh_list" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/main_tab_height" android:splitMotionEvents="false" /> </LinearLayout> </LinearLayout>
注意最后的com.gushiyingxiong.app.views.listview.PullLoadMoreListView,其本质就是一个ListView。
功能要求:
实现全屏幕的截图功能,包括ListView中滑动出现的内容。
实现思路:
由于ListView容器为了能加载大数量的Item,内部已经实现了对不可视资源的回收机制(详细可以参考: How ListView's recycling mechanism works),如果直接调用getChild的方式,会导致不可见的部分无法获取;因此,只能通过ListAdapter的getView来获取,然后调用每个item view的绘制过程,生成相关的图片,然后再拼起来,大概实现思路就是这样。
(1): 如何把View转化成图片?
我在这里参考了这篇文章:Android中View转换为Bitmap及getDrawingCache=null的解决方法
我使用了第二种方案有效,其思路也就是View的绘制流程 measure -> layout -> draw
比如ListView 的Item布局如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/stock_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FF000000" android:minHeight="80dp" android:orientation="horizontal" android:padding="10dp" > <ImageView android:id="@+id/stock_item_logo_iv" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:layout_marginRight="10dp" android:padding="1dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="right|center_vertical" android:orientation="vertical" > <TextView android:id="@+id/stock_item_earn_percent_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:text="@string/hello_world" android:textColor="#FFFFFFFF" android:textSize="14sp" android:textStyle="bold" /> </LinearLayout> </LinearLayout>
我们想要的是:
可能出来的结果却是:
原因大概是由于调用getView返回的View一般都是通过View.inflate得到的,因此在measure的过程中没有上一层父容器的尺寸参考,所以在传入measure参数为下面所示的代码的时候,就会只能刚好装下里面的View,因此看起来变短了。
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
我们可以这样子修改,指定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; List<View> childViews = null; width = getScreenWidth();//宽度等于屏幕宽 ListAdapter listAdapter = listView.getAdapter(); listItemNum = listAdapter.getCount()> childViews = new ArrayList<View>(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的部分内容没有画出来,比如下面的图:
错误的图:
正确的图:
既然有的出来了,有的没出来,羊毛肯定就出在羊身上了...
具体原因我也暂时没有分析,但是可以肯定的是布局代码出现了一些问题导致了截图的结果。(注意,在实际中下面的两种布局在界面显示上效果几乎是一致的,而只是截图中出现了问题而已)
最后把代码贴出来给大家做参考吧:
右边有出现的布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/stock_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/list_item_selector" android:minHeight="80dp" android:padding="@dimen/app_padding" > <ImageView android:id="@+id/stock_item_logo_iv" android:layout_width="@dimen/logo_img_width" android:layout_height="@dimen/logo_img_height" android:layout_gravity="center" android:layout_marginRight="10dp" android:padding="1dp" android:scaleType="fitCenter" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:minWidth="130dip" android:orientation="vertical" > <TextView android:id="@+id/stock_item_name_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:textColor="@color/text_white" android:textSize="@dimen/font_48" /> <TextView android:id="@+id/stock_item_code_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_11" /> <TextView android:id="@+id/stock_item_text_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:singleLine="true" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_11" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical|right" android:orientation="vertical" > <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/stock_item_oder_price" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_marginTop="2dip" android:singleLine="true" android:text="委托:" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_10" /> <TextView android:id="@+id/stock_item_oder_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:minWidth="@dimen/stock_list_item_oder_price_width" android:gravity="right" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginTop="2dip" android:textColor="@color/stock_high_red" android:textSize="@dimen/text_size_9" android:textStyle="bold" /> </RelativeLayout> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/stock_item_trade" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_marginTop="2dip" android:singleLine="true" android:text="实时:" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_10" /> <TextView android:id="@+id/stock_item_trade" android:layout_width="wrap_content" android:layout_height="wrap_content" android:minWidth="@dimen/stock_list_item_oder_price_width" android:gravity="right" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginTop="2dip" android:textColor="@color/text_white" android:textSize="@dimen/text_size_9" android:textStyle="bold" /> </RelativeLayout> </LinearLayout> </LinearLayout>
右边消失的布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/stock_item" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/list_item_selector" android:minHeight="80dp" android:orientation="horizontal" android:padding="@dimen/app_padding" > <ImageView android:id="@+id/stock_item_logo_iv" android:layout_width="@dimen/logo_img_width" android:layout_height="@dimen/logo_img_height" android:layout_gravity="center" android:layout_marginRight="10dp" android:padding="1dp" android:scaleType="fitCenter" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" android:minWidth="130dip" android:orientation="vertical" > <TextView android:id="@+id/stock_item_name_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:textColor="@color/text_white" android:textSize="@dimen/font_48" /> <TextView android:id="@+id/stock_item_code_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_11" /> <TextView android:id="@+id/stock_item_text_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:singleLine="true" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_11" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="right|center_vertical" android:minWidth="@dimen/stock_list_item_price_width" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical|right" > <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="2dp" android:layout_marginTop="2dip" android:gravity="center_vertical|right" android:singleLine="true" android:text="委托:" android:textColor="@color/text_gray" android:textSize="@dimen/text_size_10" /> <TextView android:id="@+id/stock_item_oder_price" android:layout_width="wrap_content" android:minWidth="@dimen/stock_list_item_oder_price_width" android:maxWidth="@dimen/stock_list_item_oder_price_width" android:layout_height="match_parent" android:layout_marginTop="2dip" android:gravity="center_vertical|right" android:singleLine="true" android:textColor="@color/stock_high_red" android:textSize="@dimen/text_size_9" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical|right" > <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="2dp" android:layout_marginTop="2dip" android:gravity="center_vertical|right" android:singleLine="true" android:textColor="@color/text_gray" android:text="实时:" android:textSize="@dimen/text_size_10" /> <TextView android:id="@+id/stock_item_trade" android:layout_width="wrap_content" android:minWidth="@dimen/stock_list_item_oder_price_width" android:maxWidth="@dimen/stock_list_item_oder_price_width" android:layout_height="match_parent" android:layout_marginTop="2dip" android:gravity="center_vertical|right" android:singleLine="true" android:textColor="@color/text_white" android:textSize="@dimen/text_size_9" android:textStyle="bold" /> </LinearLayout> </LinearLayout> </LinearLayout>
展示一下最后的截图效果:
- 解决Android界面中包含ListView的屏幕截图问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 解决scrollview中包含listview所引发的冲突问题
- Android源码中屏幕截图的实现
- Android源码中屏幕截图的实现
- android中实现屏幕截图的代码
- Android开发ListView中包含EditText控件遇到的问题
- 解决windows下android模拟器 平板模式屏幕下方无工具条的问题-有截图
- 解决当ListView的条目中包含GridView时的问题
- 解决Scrollview中包含Listview、Gridview刚进去不能置顶的问题
- Android中ListView包含CheckBox时滑动丢失选中状态的解决
- Android中ListView包含CheckBox时滑动丢失选中状态的解决
- Android中ListView包含CheckBox时滑动丢失选中状态的解决
- Android中ListView包含CheckBox时滑动丢失选中状态的解决
- Android中ListView包含CheckBox时滑动丢失选中状态的解决
- OJ积累--多个字符串的排序
- 祖国母亲
- MongoDB的find操作详解
- SSL handshake latency and HTTPS optimizations.
- 三部中國公益劇本尋愛心投資商
- 解决Android界面中包含ListView的屏幕截图问题
- 自己经常逛的网站
- 从零到App Store发布应用
- Android Support ;v4、v7、v13的区别
- 大好河山
- dfs
- CUDA远程调用—完整教程
- 【JavaSE】注解简介
- 重载运算符( 一)——学习C++笔记