关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android ListView收缩与展开的封装实现

    Android ListView收缩与展开的封装实现

    2015-03-06 00:00:00 出处:codeceo
    分享

    常有这种需求,即Listview中数据较多(不涉及分页),假如都展开,数据量较多,体验不好,所以需要提供用户查看更多、收缩数据的交互

    截图如下:

    如图所示,点击更多,则展开所有数据。点击收起,则自动收缩。

    代码如下(主要通过继承Adapetr,控制展示的数据量getCount()方法实现,当数据量大于默认值(2)时,自动只展示2条数据,当点击更多时,则展示全部数据):

    (在使用这种方法前曾想自定义ListView实现,但遇到较多问题,如:

    1.由于我们通过adapter设置数据,不直接调用listview的方法,所以需要了解Adapter中notifyDataSetChanged方法的回调函数,通过分析源码了解到notifyDataSetChanged方法会回调ListView的requestLayout方法。所以通过在requestLayout中添加动态设置listview高度的方法,但设置高度会回调requestLayout,从而造成死循环,可通过设计标志位解决

    2.动态设置listview高度并没有实现把多余的listitem隐藏,导致本该显示footview的高度显示了部分listitem。隐藏多余的listitem后,目前还是未显示出footview,通过网上了解到的一些解决办法,还是没有解决

    3.此外还有其他问题,所以后来索性转为继承BaseAdapter实现)

    package com.example.android_train.adapter;
    
    import java.util.ArrayList;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.ListAdapter;
    import android.widget.ListView;
    
    import com.example.android_train.R;
    
    public abstract class BaseFootviewAdapter<E> extends BaseAdapter {
    
        public static final int DEFAULT_SHOW_COUNT = 2;
    
        protected Context mContext;
        protected ListView mListView;
        protected LayoutInflater inflater;
        protected LinearLayout headView;
        protected Button btn_loadmore;
        protected ArrayList<E> mShowObjects = new ArrayList<E>();
        protected ArrayList<E> mAllObjects = null;
        protected boolean shrink = true;
    
        @SuppressWarnings("unused")
        private BaseFootviewAdapter() {
        }
    
        @SuppressLint("InflateParams")
        public BaseFootviewAdapter( Context mContext, ListView mListView) {
            this.mContext = mContext;
            this.mListView = mListView;
            inflater = LayoutInflater.from(mContext);
            headView = (LinearLayout) inflater.inflate(R.layout.lv_footer_button, null);
            btn_loadmore = (Button) headView.findViewById(R.id.btn_loadmore);
            btn_loadmore.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    changeShow();
                }
            });
            mListView.addFooterView(headView, null, false);
        }
    
        public void setAdapterData( ArrayList<E> mAllObjects ) {
            this.mAllObjects = mAllObjects;
            mShowObjects.clear();
            if( mAllObjects != null ) {
                if( mAllObjects.size() <= DEFAULT_SHOW_COUNT ) {
                    headView.setVisibility(View.GONE);
                    mShowObjects.addAll(mAllObjects);
                } else {
                    headView.setVisibility(View.VISIBLE);
                    for (int i = 0; i < DEFAULT_SHOW_COUNT; i++) {
                        mShowObjects.add(mAllObjects.get(i));
                    }
                }
            }
            notifyDataSetChanged();
            setListViewHeightBasedOnChildren(mListView);
        }
    
        @Override
        public int getCount() {
            int showCount = 0;
            if( mShowObjects != null ) {
                showCount = mShowObjects.size();
            }
            return showCount;
        }
    
        @Override
        public E getItem(int position) {
            E object = null;
            if( mShowObjects != null ) {
                object = mShowObjects.get(position);
            }
            return object;
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        private void changeShow() {
            if( headView.getVisibility() == View.GONE ) {
                headView.setVisibility(View.VISIBLE);
            }
            mShowObjects.clear();
            if( shrink ) {
                shrink = false;
                mShowObjects.addAll(mAllObjects);
                btn_loadmore.setText("收起");
            } else {
                shrink = true;
                for (int i = 0; i < DEFAULT_SHOW_COUNT; i++) {
                    mShowObjects.add(mAllObjects.get(i));
                }
                btn_loadmore.setText("更多");
            }
            notifyDataSetChanged();
            setListViewHeightBasedOnChildren(mListView);
        }
    
        /**
         * 当ListView外层有ScrollView时,需要动态设置ListView高度
         * @param listView
         */
        protected void setListViewHeightBasedOnChildren(ListView listView) { 
            if(listView == null) return;
            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)); 
            listView.setLayoutParams(params); 
        }
    
    }

    资源文件lv_footer_button.xml(此处需注意,不要在fl_loadmore这个外部LinearLayout设置高度,而应在Button中设置,否则listview展示的高度与设置的不符(暂不了解原因))

    < xml version="1.0" encoding="utf-8" >
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fl_loadmore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:orientation="vertical" >
    
        <LinearLayout android:layout_width="match_parent"
            android:layout_height="1px"
            android:orientation="vertical"
            android:background="#000000"/>
    
        <Button
            android:id="@+id/btn_loadmore"
            android:layout_width="match_parent"
            android:layout_height="32dp"
            android:gravity="center"
            android:background="#00000000"
            android:text="更多"
            android:textSize="14sp" />
    
    </LinearLayout>

    外部调用例子:

    对象Bean(StationImage):

    package com.example.android_train.bean;
    
    public class StationImage {
    
        public String img_name = "";
        public String img_url_s = "";
        public String img_url_l = "";
    
        public String getImg_name() {
            return img_name;
        }
    
        public void setImg_name(String img_name) {
            this.img_name = img_name;
        }
    
        public String getImg_url_s() {
            return img_url_s;
        }
    
        public void setImg_url_s(String img_url_s) {
            this.img_url_s = img_url_s;
        }
    
        public String getImg_url_l() {
            return img_url_l;
        }
    
        public void setImg_url_l(String img_url_l) {
            this.img_url_l = img_url_l;
        }
    
    }

    FootviewAdapter继承BaseFootviewAdapter,并实现getView()方法

    package com.example.android_train.adapter;
    
    import android.content.Context;
    import android.graphics.Paint;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import com.example.android_train.R;
    import com.example.android_train.bean.StationImage;
    
    public class FootviewAdapter extends BaseFootviewAdapter<StationImage>{
    
        private ListItemView listItemView = null;
    
        public final class ListItemView {
            public LinearLayout gas_station_groupon_ll;
            public TextView gpn_name;
            public TextView gpn_price;
            public TextView gpn_old_price;
        }
    
        public FootviewAdapter( Context mContext, ListView mListView) {
            super(mContext, mListView);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final StationImage object = (StationImage)getItem(position);
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.lv_gas_station_detail_groupon, parent, false);
                listItemView = new ListItemView();
                creatView(convertView, listItemView);
                convertView.setTag(listItemView);
            } else {
                listItemView = (ListItemView) convertView.getTag();
            }
            listItemView.gpn_name.setText(object.getImg_name());
            listItemView.gpn_price.setText("¥" + object.getImg_url_l());
            listItemView.gpn_old_price.setText("¥" + object.getImg_url_s());
            listItemView.gpn_old_price.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG); //中划线
            return convertView;
        }
    
        private void creatView(View rowView, ListItemView listItemView) {
            listItemView.gas_station_groupon_ll = (LinearLayout) rowView.findViewById(R.id.gas_station_groupon_ll);
            listItemView.gpn_name = (TextView) rowView.findViewById(R.id.gpn_name);
            listItemView.gpn_price = (TextView) rowView.findViewById(R.id.gpn_price);
            listItemView.gpn_old_price = (TextView) rowView.findViewById(R.id.gpn_old_price);
        }
    
    }

    资源文件(lv_gas_station_detail_groupon)如下:

    < xml version="1.0" encoding="utf-8" >
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/gas_station_groupon_ll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:paddingLeft="16dp"
            android:paddingRight="16dp" >
    
            <TextView
                android:id="@+id/gpn_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:text="ahah"
                android:textSize="16sp" />
    
            <TextView
                android:id="@+id/gpn_price"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_alignParentLeft="true"
                android:layout_marginRight="16dp"
                android:singleLine="true"
                android:text="abc" />
    
            <TextView
                android:id="@+id/gpn_old_price"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_toRightOf="@id/gpn_price"
                android:singleLine="true"
                android:text="qew"
                android:textSize="16sp" />
        </RelativeLayout>
    
    </LinearLayout>

    Activity中的调用(实例化FootviewAdapter子类,然后设置相应数据即可):

    ArrayList<StationImage> mStationImages = new ArrayList<StationImage>();
    ListView listview = null;
    for (int i = 0; i < 5; i++) {
        StationImage mStationImage = new StationImage();
        mStationImage.setImg_name("第" + i + "个项目的名字");
        mStationImage.setImg_url_l("第" + i + "个项目的长URL");
        mStationImage.setImg_url_s("第" + i + "个项目的短URL");
        mStationImages.add(mStationImage);
    }
    listview = (ListView) findViewById(R.id.listview);
    FootviewAdapter mFootviewAdapter = new FootviewAdapter(this, listview);
    listview.setAdapter(mFootviewAdapter);
    mFootviewAdapter.setAdapterData(mStationImages);
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    电脑屏幕不小心竖起来了?别慌,快捷键搞定

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    IT头条

    Synology 更新 ActiveProtect Manager 1.1 以增强企业网络弹性和合规性

    00:43

    新的 Rubrik Agent Cloud 加速了可信的企业 AI 代理部署

    00:34

    宇树科技 G1人形机器人,拉动一辆重达1.4吨的汽车

    00:21

    Cloudera 调查发现,96% 的企业已将 AI 集成到核心业务流程中,这表明 AI 已从竞争优势转变为强制性实践

    02:05

    投资者反对马斯克 1 万亿美元薪酬方案,要求重组特斯拉董事会

    01:18

    技术热点

    大型网站的 HTTPS 实践(三):基于协议和配置的优化

    ubuntu下右键菜单添加新建word、excel文档等快捷方式

    Sublime Text 简明教程

    用户定义SQL Server函数的描述

    怎么在windows 7开始菜单中添加下载选项?

    SQL Server 2016将有哪些功能改进?

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。