文档章节

Android界面中包含ListView的屏幕截图问题记录

叶大侠
 叶大侠
发布于 2014/10/13 22:25
字数 1616
阅读 88
收藏 0
点赞 0
评论 0

界面的布局情况:

<?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>

功能要求:实现全屏幕的截图功能,包括ListView中滑动出现的内容。

实现思路:由于ListView容器为了能加载大数量的Item,内部已经实现了对不可视资源的回收机制(详细可以参考: How ListView's recycling mechanism works),如果直接调用getChild的方式,会导致不可见的部分无法获取;因此,只能通过ListAdapter的getView来获取,然后调用每个item view的绘制过程,生成相关的图片,然后再拼起来,大概实现思路就是这样。

这里首先要解决的一个问题是:如何把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.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;
    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>

最后分享一张成功截图全貌:

原文:http://www.darcye.com/article/84263064

© 著作权归作者所有

共有 人打赏支持
叶大侠

叶大侠

粉丝 56
博文 44
码字总数 67312
作品 5
广州
程序员
Android 渗透测试学习手册 第七章 不太知名的 Android 漏洞

第七章 不太知名的 Android 漏洞 作者:Aditya Gupta 译者:飞龙 协议:CC BY-NC-SA 4.0 在本章中,我们将了解一些不太知名的 Android 攻击向量,这在 Android 渗透测试中可能很有用。 我们还...

apachecn_飞龙 ⋅ 2016/12/08 ⋅ 0

android蓝牙手柄、仿QQ看房、仿慕课网、数据库二维码框架等源码

Android精选源码 可自定义图片指示器并支持自定义Tab宽度的TabLayout源码(http://www.apkbus.com/thread-599243-1-1.html) android蓝牙控制手柄操作源码(http://www.apkbus.com/thread-59928...

逆鳞龙 ⋅ 05/15 ⋅ 0

使用Python制作微信跳一跳半自动外挂+详细注释

思路 1.截取安卓手机当前屏幕图片并复制到Mac。 知识点:ADB工具--截屏命令 2.测量截图中两方块之间的距离。知识点:Matplotlib制图工具 3.根据距离判断手机所需按下的时间。 4.通过鼠标控制...

earth9 ⋅ 04/16 ⋅ 0

构建第一个Jetpack app

启动Android Studio3.2或更高的版本,然后创建Android Project 在Add an Activity to Mobile界面,提供了很多模板,选择Activity & Fragment + ViewModel模板,旨在轻松的将jetpack引入到您的...

小菜鸟程序媛 ⋅ 05/15 ⋅ 0

Android 渗透测试学习手册 第一章 Android 安全入门

第一章 Android 安全入门 作者:Aditya Gupta 译者:飞龙 协议:CC BY-NC-SA 4.0 Android 是当今最流行的智能手机操作系统之一。 随着人气的增加,它存在很多安全风险,这些风险不可避免地被...

apachecn_飞龙 ⋅ 2016/12/06 ⋅ 0

Android源码剖析之Framework层进阶版(Wms窗口管理)

本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 上一篇我们主要讲了Ams,篇幅有限,本篇再讲讲Wms,即WindowManagerService,管理窗口的服务。主要负责窗口的创建、删除、...

liuzxgeek ⋅ 2016/08/26 ⋅ 0

【Android 开发入门】Android Studio 下载及安装

android 开发工具主流的还是Android Studio,当然也有很多人喜欢用Eclipse,也有人喜欢用IntelliJ IDEA ;还有Xamarin这种只需要编写一次代码,可以编译多种平台可运行的强大工具。但是它又真...

微wx笑 ⋅ 2016/09/11 ⋅ 0

Android实现微信自动抢红包

Android实现微信自动抢红包 简介 本文介绍微信自动抢红包的实现方法,主要实现以下几个功能: 自动拆开屏幕上出现的红包 处于桌面或聊天列表时接收到红包信息时自动进入聊天界面并拆红包 日志...

oden ⋅ 2016/08/27 ⋅ 0

Android 面试题总结之Android 基础(六)

Android 面试题总结之Android 基础(六) 在上一章节Android 面试题总结之Android 基础ListView(五) 主要是ListView的优化,原理以及一些基本问题。 在阅读过程中有任何问题,请及时联系。...

fuchenxuan ⋅ 2016/05/30 ⋅ 1

Android P 应用兼容常见错误及建议

从 2018 年 3 月初我们发布 Android P 开发者预览版以来,很多开发者都对当前常见应用在 Android P 上做了一些兼容性测试,我们在这里总结了一些常见的问题,以及它们发生的原因和建议的修改...

谷歌开发者 ⋅ 04/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

IDEA PermGen space内存溢出

解决方案: File -> Settings -> Build, Execution, Deployment / Build Tools / Maven / Runner下,找到VM Options选项,默认是空的,改为如下内容(或更大值)...

快乐的小火柴 ⋅ 13分钟前 ⋅ 0

前端常见跨域解决方案

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。 广义的跨域: 1.) 资源跳转: A链接、重定向、表单提交2.) 资源嵌入: <link>、<script>、<im...

临江仙卜算子 ⋅ 13分钟前 ⋅ 0

系统管理命令service

service命令用来控制系统服务的实用工具,例如启动、停止、重启和关闭系统服务,以及当前状态。当然也可以直接操作,例如/etc/init.d/mysqld restart等。 语法 service (选项)(参数) 选项...

Jpchina ⋅ 18分钟前 ⋅ 0

MySQL 联合索引的命中规则

为什么要用联合索引? 对于查询语句“SELECT T.* FROM T WHERE T.c1=1 AND T.c3=2”涉及到两列,这个时候我们一般采用一个联合索引(c1, c3);而不用两个单列索引,这是因为一条查询语句往往应...

hensemlee ⋅ 26分钟前 ⋅ 0

Spring 自动组件扫描

通常情况下都是在XML配置文件中手动声明Bean和组件的。不过Spring也可以自动扫描组件实例化Bean,这样就可以避免在XML文件中繁琐的Bean声明。 手动声明Bean: 这里不再啰嗦,就是简单地在XML...

霍淇滨 ⋅ 30分钟前 ⋅ 0

MapReduce简单需求分析-共同好友及查找互粉的情况

MapReduce的设计,最重要的是要找准key,然后制定一系列的数据处理流程。MapReduce的Map中,会把key相同的分配到同一个reduce中,对于key的选择,可以找到某个相同的因素。以下面的几个例子说...

Jason_typ ⋅ 32分钟前 ⋅ 0

springboot多数据源自动切换

SpringBoot多数据源切换,先上配置文件: 1.pom: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20......

JackyRiver ⋅ 34分钟前 ⋅ 0

Boost库编译应用

版本:Boost 1.66.0 Windows库编译 官网指南:直接执行bootstrap.bat处理文件即可,可以我却遇到一堆的问题。 环境:Windows 10 + Visual Studio 2017 Boost编译出来库命名 boost库生成文件命...

水海云 ⋅ 39分钟前 ⋅ 0

解决Eclipse发布到Tomcat丢失依赖jar包的问题

如果jar文件是以外部依赖的形式导入的。Eclipse将web项目发布到Tomcat时,是不会自动发布这些依赖的。 可以通过Eclipse在项目上右击 - Propertics - Deployment Assembly,添加“Java Build ...

ArlenXu ⋅ 39分钟前 ⋅ 0

iview tree组件层级过多时可左右滚动

使用vue+iview的tree组件,iview官网iview的tree树形控件 问题描述:tree层级过多时左右不可滚动 问题解决:修改overflow属性值 .el-tree-node>.el-tree-node_children { overflow: vi...

YXMBetter ⋅ 41分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部