解决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>


展示一下最后的截图效果:

0 0
原创粉丝点击