Android listView的展开与收起实现折叠,及动态设置子ListView的高度_listview折叠_tsaopin的博客-程序员秘密

技术标签: ListView  ListView折叠  展开收起  android  android listview  动态ListView  

问题重现

最近在公司项目中做一个商品展示的功能,要求在分类后 ,对每个类进行展开、收起操作。想法就是在ListView中嵌套一个ListView,通过动态的显示和隐藏ListView,实现展开和收起操作在同一个页面,实现折叠效果。难点:解决ListView的动态设置问题.先看效果图:

这里写图片描述
这里写图片描述

解决思路

外面一层是一个ListView,在填充Item的时候,在Item布局设置为LinearLayout,在下面设置一个ListView,默认为gone。在ListView适配器中动态设置显示和隐藏ListView,显示的时候通过子适配器填充数据,同时设置字ListView动态高度,以便解决之前的只显示一条的问题。

主页面布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >
    <ListView
        android:id="@+id/pro_lv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>
</RelativeLayout>

两个Item布局

item_produces.xml(大ListView Item)实现了分层的Franlayout,效果:图片上有布局。

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <View
            android:layout_width="match_parent"
            android:layout_height="10dp"
            android:background="#F6F5F4" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/tv_control"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignParentTop="true"
                android:layout_marginRight="10dp"
                android:clickable="true"
                android:padding="5dp"
                android:text="展开更多"
                android:textColor="#99000000"
                android:textSize="14sp" />

            <TextView
                android:id="@+id/tv_pro_all"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="11dp"
                android:padding="5dp"
                android:text="美妆专场"
                android:textColor="#000000"
                android:textSize="14sp" />
        </RelativeLayout>
    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="5dp" >

        <ImageView
            android:id="@+id/iv_produce"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:orientation="horizontal" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="2dp"
                android:layout_weight="1"
                android:background="#e000BE93"
                android:padding="5dp"
                android:text="当前价:¥189"
                android:textSize="12sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#e000BE93"
                android:padding="5dp"
                android:text="¥899"
                android:textSize="12sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#e000BE93"
                android:padding="5dp"
                android:text="开始06-18 18:00"
                android:textSize="12sp" />
        </LinearLayout>

        <TextView
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="#e000BE93"
            android:text="02:00:18"
            android:textSize="12sp" />
    </FrameLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/tv_prod_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:padding="5dp"
            android:text="兰蔻最新季护肤套装"
            android:textColor="#000000"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_baoming"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="15dp"
            android:text="报名"
            android:textColor="#1FDCAC"
            android:textSize="14sp" />
    </RelativeLayout>


    <ListView
        android:id="@+id/lv_more_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         android:dividerHeight="0.0dip"
         android:fadingEdge="none"
        android:visibility="gone" >
    </ListView>

小ListView Item 布局 一定要在布局外面加上LinearLayout,不然会抛异常。

<LinearLayout
        android:id="@+id/ll_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <View
            android:layout_width="match_parent"
            android:layout_height="10dp"
            android:background="#F6F5F4" />



    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="5dp" >

        <ImageView
            android:id="@+id/iv_more"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:orientation="horizontal" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="2dp"
                android:layout_weight="1"
                android:background="#e000BE93"
                android:padding="5dp"
                android:text="当前价:¥1189"
                android:textSize="12sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#e000BE93"
                android:padding="5dp"
                android:text="¥899"
                android:textSize="12sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#e000BE93"
                android:padding="5dp"
                android:text="开始06-18 18:00"
                android:textSize="12sp" />
        </LinearLayout>

        <TextView
            android:layout_margin="10dp"
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#e000BE93"
            android:text="02:00:18"
            android:textSize="12sp" />
    </FrameLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/tv_more_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:padding="5dp"
            android:text="兰蔻最新季护肤套装"
            android:textColor="#000000"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_baoming"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="15dp"
            android:text="报名"
            android:textColor="#1FDCAC"
            android:textSize="14sp" />
    </RelativeLayout>

</LinearLayout>

主要功能代码

数据的填充,为适配器Adapter准备数据

//填充数据
    private List<Map<String, Object>> getData() {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = new HashMap<String, Object>();//Map集合填充数据

        String exlist_adapter = "1234";
        map.put("exlist_adapter", exlist_adapter);
        map.put("zhuanchang", "美妆专场");
        map.put("info", "兰蔻最新季护肤套装");
        map.put("img", R.drawable.pro);
        list.add(map);

点击展开,点击收起的代码

final TextView tv_control = (TextView) convertView.findViewById(R.id.tv_control);
                final TextView tv_baoming = (TextView) convertView.findViewById(R.id.tv_baoming);
                //默认隐藏的ListView
                final ListView listmore = (ListView) convertView
                        .findViewById(R.id.lv_more_list);//展开的布局

                tv_control.setOnClickListener(new OnClickListener() {
                    boolean isOpened = false;//改变展开状态
                    @Override
                    public void onClick(View v) {
                        if (!isOpened) {
                            listmore.setVisibility(View.VISIBLE);
                            tv_control.setText("收起");
                            isOpened = true;
                        }else {
                            listmore.setVisibility(View.GONE);
                            tv_control.setText("展开更多");
                            isOpened = false;
                        }

                    }
                });
                tv_baoming.setOnClickListener(new OnClickListener() {
   //报名按钮

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub

                    }
                });

在大ListView的适配器中要初始化要显示的ListView即点击展开的部分。setListViewHeightBasedOnChildren(listmore);为加载数据的时候根据条目动态设置ListView的高度。如果不进行次设置,会出现只显示一个条目的错误。

final ListView listmore = (ListView) convertView
                        .findViewById(R.id.lv_more_list);
Madapter madapter = new Madapter(getApplicationContext());

                listmore.setAdapter(madapter);
                setListViewHeightBasedOnChildren(listmore);

动态设置ListView的高度,主要就是获得所有Item的高度总和,设置给ListView即可



          ListAdapter listAdapter = listView.getAdapter();  

          if (listAdapter == null) {  
           return;  
          }  

          int totalHeight = 0;  

          for (int i = 0; i < listAdapter.getCount(); i++) {  
           View listItem = listAdapter.getView(i, null, listView);  
           listItem.measure(0, 0);  
           totalHeight += listItem.getMeasuredHeight();  
          }  

          ViewGroup.LayoutParams params = listView.getLayoutParams();  

          params.height = totalHeight  
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));  

          ((MarginLayoutParams) params).setMargins(10, 10, 10, 10); // 可删除  

          listView.setLayoutParams(params);  

至此功能实现。

点击源码下载

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tsaopin/article/details/47338779

智能推荐

C-入门-数据之间的转换_数据间转换c_die Ewigkeit -en的博客-程序员秘密

数据之间的转换#include&lt;stdio.h&gt;int main(void) { short e = 32767; //段整形也可写为 short int printf("short类型的结果为:%d\n", e); int f = e; printf("int类型的结果为:%d\n", f); int g = 2000025; printf("int类型的结果...

EJB详解_去ejb_王雪芬-Judy领袖的博客-程序员秘密

前言从最开始学习javaEE的时候,Ejb的传说就开始漫天飞,而且特别懵根本不知道Ejb是容器还是组件!为什么他就是核心了呢?为什么他就可以分布在不同的服务器上呢?还可以远程调用,还有就是什么是javabean啊,简直就是一肚子问题?憋了好几天一直都不懂!还好现在有一点的了解分享给大家What EJBEjb是sun公司javaEE服务器端组件模型,设计的目标和核心是为了应用部署分布式应用程序,简单说

使用RTP包荷载H264码流数据_h264 payload_椛茶的博客-程序员秘密

在音视频通话中我们通常使用 RTP 协议包荷载音视频码流数据,例如用户摄像头采集图像后进行编码成帧,再将帧数据拆分到 RTP 协议包后发送到流媒体服务器,本文将介绍如何使用 JRTPLIB 发送 H264 码流数据。

idea为java程序添加启动参数(program arguments,vm arguments,Environment variable),并在程序中获取使用_idea vm参数配置_T-OPEN的博客-程序员秘密

idea为java程序添加启动参数(program arguments,vm arguments,Environment variable),并在程序中获取使用

CT介绍_czjjun的博客-程序员秘密

什么是CT全称:computed tomographyCT是一种功能齐全的病情探测仪器,它是电子计算机X射线断层扫描技术简称。CT的工作程序是这样的:它根据人体不同组织对X线的吸收与透过率的不同,应用灵敏度极高的仪器对人体进行测量,然后将测量所获取的数据输入电子计算机,电子计算机对数据进行处理后,就可摄下人体被检查部位的断面或立体的图像,发现体内任何部位的细小病变。CT的发明自从X射线发现后,医

putc()与fputc()_fputc() putc()_C_linux记事的博客-程序员秘密

fputc()与putc():输出一字符到指定流中。对于fputc():fputc(char ch, FILE * fp):在fp所指向的文件的当前文件写入一个字符, 写入成功返回写入的字符的ASII吗, 否则返回EOF。fputc()与putc()的功能与用法一样。以为为putc()不同于fputc()的例子:#include int main(void){char msg[] = "He

随便推点

【arcpy项目实战】将两两生成的最短路径pyhon代码封装入script中,作为arcgis的工具直接调用_桃花浪子立的博客-程序员秘密

【需求】之前的两两点相连接的最短路径为单纯的pyhon代码,用户需要修改文件路径才能正常使用,为了给用户提供更多的方便,我将pyhon代码封装到arcgis的工具中,通过接受用户输入文件,实现可视的文件生成。【分析】需要对代码进行封装,首先要需要用户选择输入的元素,程序运行的方法等,下面即为具体的分析。 接下来,讲一下这个封装过程。封装即为建立script tool工具来实现复杂的gp...

SORT 目标跟踪算法源码分析_sort跟踪算法代码包_ciky奇的博客-程序员秘密

有关SORT的论文早先就已经拜读过了,一直想写这篇文章的源码解析,终于有时间来写了。论文解读请参考:SIMPLE ONLINE AND REALTIME TRACKING (SORT)论文阅读笔记论文地址:https://arxiv.org/abs/1602.00763github地址:https://github.com/abewley/sort以下用到的图片转自HaoBB...

python 内建函数range/math.ceil/math.floor_语默静喧的博客-程序员秘密

1、range()(1)range(stop) -> 返回整型元素数组(2)range(start, stop[, step]) -> 返回整形元素类型的数组range(m,n) --------->[m,m+1,m+2 ... n-2,n-1]共n-m个元素,为前闭后开的区间[m,n)start元素在默认情况为0step则确定了增长(减小)的幅度例:range(1,10,

OneNET分享完结篇 | 让你的设备连接上OneNET平台_连接onenet_程序员小哈的博客-程序员秘密

大家好,我是程序员小哈。今天把OneNET相关内容的分享做一个收尾,这一个系列的分享,正好也是对应之前的一个网友问答:STM32→ESP8266→OneNET ,对应整个技术路线涉及知识点的概括,希望我的分享,可以带给你些许帮助。实现目标要想实现最终目标,我们需要解决如下几个问题:一个支持MQTT协议的工程STM32与ESP8266之间一般选择串口通信,所以要实现ESP8266串口数据的收发传感器数据的上传,串口数据的方向为 STM32–&gt;ESP8266 ,对应ESP8266串口数据的接

Dart之Future_dart future_乌克丽丽丶的博客-程序员秘密

FutureDart类库有非常多的返回Future或者Stream对象的函数。 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作。而不是等到这个操作完成。async和await关键词支持了异步编程,允许您写出和同步代码很像的异步代码。1. Future.then使用 Future.delayed 模拟一个耗时操作,2秒后返回字符串“Hello Dart”,然后在then中接收到异步返回值,并打印出来:Future.delayed(new Duration(seco

C语言:判断奇数偶数_c语言判断奇偶性的程序怎么写_叫我乂可好的博客-程序员秘密

//1.输入一个整数,判断奇数偶数//2.输入一个数据,如果a &gt; b,则输出 a-b的值,并求a与b的余数;//否则,输出b-a的值,并求出ab之间的商//3.输入三角形的边长,求出三角形的周长,面积和,若不能构成,则提示出来,#include &lt;stdio.h&gt;int main(int argc, char const *argv[]){int a;printf(“输入一个整数,判断奇数偶数:\n”);scanf("%d",&amp;a);if(a % 2 == 0

推荐文章

热门文章

相关标签