ExpandableListView二级分栏详解完美用法

对ExpandableListView控件进行封装(未自定义)直接上代码:

通用ViewHolder类,仅在setImageResource中添加代码

package com.svp.haoyan.expandablelistview.tool;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by haoyan on 2016/3/24.
 */
public class ViewHolder {
    //存储数据
    private SparseArray<View> mViews;

    private  int mPosition;
    private View mConvertView;
    private boolean misExpanded;
    public ViewHolder(Context context, ViewGroup parent, int layoutId, int position,boolean isExpanded) {

        this.mPosition=position;
        this.mViews= new SparseArray<View>();
        this.misExpanded=isExpanded;
        //三
        mConvertView= LayoutInflater.from(context).inflate(layoutId,parent,false);
        //一
        mConvertView.setTag(this);
    }
    public static ViewHolder get(Context context,View convertView,
                                 ViewGroup parent,int layoutId,int position,boolean isExpanded){

        if (convertView==null){
            return new ViewHolder(context,parent,layoutId,position,isExpanded);
        }else {
            //五 六
            ViewHolder holder=(ViewHolder)convertView.getTag();
            holder.mPosition=position;
            return holder;
        }
    }
    //通过viewId获取控件
    //泛型T返回子类
    public <T extends View> T getView(int viewId){

        View view =mViews.get(viewId);
        if (view==null){
            //四
            view=mConvertView.findViewById(viewId);
            mViews.put(viewId,view);
        }
        return (T)view;
    }
    //八
    public View getmConvertView() {
        return mConvertView;
    }

    /**
     * 设置TextView的值
     * @param viewId
     * @param text
     * @return
     */
    //四 七 九
    public ViewHolder setText(int viewId,String text){
        TextView tv= getView(viewId);
        tv.setText(text);
        return this;
    }
    /**
     * 一参传id,二参传图片地址,三参为true则调用点击变化效果,默认为false.
     * */
    public ViewHolder setImageResource(int viewId,int resId,boolean expanded){
        ImageView view= getView(viewId);
        view.setImageResource(resId);
        if (expanded){
            if (misExpanded){
                view.setVisibility(View.GONE);
            }else {
                view.setVisibility(View.VISIBLE);
            }
        }
        return this;
    }
    public ViewHolder setImageBitamp(int viewId,Bitmap bitmap){
        ImageView view= getView(viewId);
        view.setImageBitmap(bitmap);
        return this;
    }
    public ViewHolder setImageURI(int viewId,String uri){
        ImageView view= getView(viewId);
//        Imageloader.getInstance().loadImg(view,uri);
        return this;
    }

}

实体类Expand_DTO:

package com.svp.haoyan.expandablelistview.dto;

/**
 * Created by haoyan on 2016/5/7.
 */
public class Expand_DTO {

    private String name;
    private String contents;
    private int pic;
    private int photo;

    public static class Expand_child {
        private String childname;
        private String childcont;

        public String getChildname() {
            return childname;
        }

        public void setChildname(String childname) {
            this.childname = childname;
        }

        public String getChildcont() {
            return childcont;
        }

        public void setChildcont(String childcont) {
            this.childcont = childcont;
        }
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }

    public int getPic() {
        return pic;
    }

    public void setPic(int pic) {
        this.pic = pic;
    }

    public int getPhoto() {
        return photo;
    }

    public void setPhoto(int photo) {
        this.photo = photo;
    }

}

接下来是最主要的Adapter:

package com.svp.haoyan.expandablelistview;

import android.content.Context;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;

import com.svp.haoyan.expandablelistview.tool.ViewHolder;

import java.util.List;
import java.util.Map;

/**
 * Created by haoyan on 2016/4/28.
 */
public abstract class MyExpandableListAdapter<T,F>implements ExpandableListAdapter {
    private Context mcontext;
    private List<T> mexpand_dtos;
    private Map<Integer, List<F>> mmap = null;
    public MyExpandableListAdapter(Context context, List<T> expand_dtos,Map<Integer, List<F>> map) {
        this.mcontext = context;
        this.mexpand_dtos = expand_dtos;
        this.mmap=map;
    }
    /*注册一个观察者(observer),当此适配器数据修改时即调用此观察者。*/
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {

    }
    /*取消先前通过registerDataSetObserver(DataSetObserver)方式注册进该适配器中的观察者对象*/
    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {

    }
    /*获取组的个数*/
    @Override
    public int getGroupCount() {
        return mexpand_dtos.size();
    }
    /*返回在指定Group的Child数目。*/
    @Override
    public int getChildrenCount(int groupPosition) {
        return mmap.get(groupPosition).size();
    }
    //获取当前父item的数据
    @Override
    public T getGroup(int groupPosition) {
        return mexpand_dtos.get(groupPosition);
    }
    /*获取与在指定group给予child相关的数据。*/
    @Override
    public F getChild(int groupPosition, int childPosition) {
        return (mmap.get(groupPosition).get(childPosition));
    }
    /*获取指定组的ID*/
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
    //得到子item的ID
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
    //组和子元素是否持有稳定的ID,也就是底层数据的改变不会影响到它们。(没效果)
    @Override
    public boolean hasStableIds() {
        return true;
    }
    //设置父item组件
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = ViewHolder.get(mcontext, convertView, parent, R.layout.expand_groupview, groupPosition,isExpanded);
        convert(viewHolder, getGroup(groupPosition));
        return viewHolder.getmConvertView();
    }
    //自己写
    public abstract void convert(ViewHolder viewHolder, T t);

    public abstract void convertchild(ViewHolder viewHolder, F f);
    //设置子item的组件
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = ViewHolder.get(mcontext, convertView, parent, R.layout.expand_childview, groupPosition,isLastChild);
        convertchild(viewHolder, getChild(groupPosition,childPosition));
        return viewHolder.getmConvertView();
        /*子元素是否处于组中的最后一个(对每个组的最后一个进行操作)*/
        //boolean isLastChild
        /*下边是未封装代码,提供参考*/
//        String Childname = (mmap.get(groupPosition).get(childPosition)).getChildname();
//        LayoutInflater inflater = (LayoutInflater)mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//        convertView = inflater.inflate(R.layout.expand_childview, null);
//        TextView tv_child = (TextView) convertView.findViewById(R.id.tv_child);
//        tv_child.setText(Childcont);
    }
    /*是否选中指定位置上的子元素。*/
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
    /*true所有条目可以选择和点击*/
    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }
    /*如果当前适配器不包含任何数据则返回True。经常用来决定一个空视图是否应该被显示。
    一个典型的实现将返回表达式getCount() == 0的结果,但是由于getCount()包含了头部和尾部,适配器可能需要不同的行为。*/
    @Override
    public boolean isEmpty() {
        return false;
    }
    /*当组展开状态的时候此方法被调用。*/
    @Override
    public void onGroupExpanded(int groupPosition) {

    }
    /*当组收缩状态的时候此方法被调用。*/
    @Override
    public void onGroupCollapsed(int groupPosition) {

    }
    /*根据所给的子ID号和组ID号返回唯一的ID。此外,若hasStableIds()是true,那么必须要返回稳定的ID。*/
    @Override
    public long getCombinedChildId(long groupId, long childId) {
        return 0;
    }
    /*同上*/
    @Override
    public long getCombinedGroupId(long groupId) {
        return 0;
    }
}

最后是调用类Activity:

package com.svp.haoyan.expandablelistview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ExpandableListView;

import com.svp.haoyan.expandablelistview.dto.Expand_DTO;
import com.svp.haoyan.expandablelistview.tool.ViewHolder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private ExpandableListView elistview;
    private List<Expand_DTO> expanddata;
    private HashMap<Integer, List<Expand_DTO.Expand_child>> map = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dataView();
        expandView();
    }

    private void expandView() {
        elistview = (ExpandableListView) findViewById(R.id.expandable_lv);
        elistview.setAdapter(new MyExpandableListAdapter<Expand_DTO,Expand_DTO.Expand_child>(this, expanddata,map) {
            @Override
            public void convert(ViewHolder viewHolder, Expand_DTO expand_dto) {
                viewHolder.setText(R.id.tv_expand, expand_dto.getName())
                        .setText(R.id.tv_expand_two, expand_dto.getContents())
                        .setImageResource(R.id.img_expand, expand_dto.getPic(),false)
                        .setImageResource(R.id.img_expand_two, expand_dto.getPhoto(),false);
            }

            @Override
            public void convertchild(ViewHolder viewHolder, Expand_DTO.Expand_child expand_child) {
                viewHolder.setText(R.id.tv_child,expand_child.getChildname())
                          .setText(R.id.tv_child2,expand_child.getChildcont());
            }
        });
        //去掉自带箭头
        elistview.setGroupIndicator(null);
    }

    private void dataView() {
        expanddata = new ArrayList<Expand_DTO>();
        Expand_DTO bean_zero = new Expand_DTO();
        bean_zero.setName("android新技能1");
        bean_zero.setContents("1");
        bean_zero.setPic(R.drawable.icon_check);
        bean_zero.setPhoto(R.drawable.travel_airfare_cn_position);
        expanddata.add(bean_zero);

        Expand_DTO bean_one = new Expand_DTO();
        bean_one.setName("android新技能2");
        bean_one.setContents("2");
        bean_one.setPic(R.drawable.icon_check);
        bean_one.setPhoto(R.drawable.travel_airfare_cn_position);
        expanddata.add(bean_one);

        Expand_DTO bean_two = new Expand_DTO();
        bean_two.setName("android新技能3");
        bean_two.setContents("3");
        bean_two.setPic(R.drawable.icon_check);
        bean_two.setPhoto(R.drawable.travel_airfare_cn_position);
        expanddata.add(bean_two);

        //这里可以使用SparseArray优化性能
        map = new HashMap<Integer, List<Expand_DTO.Expand_child>>();
        List<Expand_DTO.Expand_child> expand_children_zero=new ArrayList<Expand_DTO.Expand_child>();
        Expand_DTO.Expand_child child1=new Expand_DTO.Expand_child();
        child1.setChildname("11111");
        child1.setChildcont("22222");
        expand_children_zero.add(child1);

        Expand_DTO.Expand_child child2=new Expand_DTO.Expand_child();
        child2.setChildname("3333333");
        child2.setChildcont("4444444");
        expand_children_zero.add(child2);
        map.put(0,expand_children_zero);

        List<Expand_DTO.Expand_child> expand_children_one=new ArrayList<Expand_DTO.Expand_child>();
        Expand_DTO.Expand_child child3=new Expand_DTO.Expand_child();
        child3.setChildname("55555");
        child3.setChildcont("66666");
        expand_children_one.add(child3);

        Expand_DTO.Expand_child child4=new Expand_DTO.Expand_child();
        child4.setChildname("77777");
        child4.setChildcont("88888");
        expand_children_one.add(child4);
        map.put(1,expand_children_one);

        List<Expand_DTO.Expand_child> children_data_two=new ArrayList<Expand_DTO.Expand_child>();
        Expand_DTO.Expand_child child5=new Expand_DTO.Expand_child();
        child5.setChildname("99999");
        child5.setChildcont("00000");
        children_data_two.add(child5);

        Expand_DTO.Expand_child child6=new Expand_DTO.Expand_child();
        child6.setChildname("12345");
        child6.setChildcont("54321");
        children_data_two.add(child6);
        map.put(2,children_data_two);

    }
}

完活布局很简单就不贴出来了,加上图片有图有真相:

附上写的很好的链接:

ExpandableListView基础写法(数组数据)

ExpandableListView(列表数据)

ExpandableListView二级列表(理论知识)

ExpandableListView实现三级扩展列表

下面是源码链接:

源码链接

时间: 2024-08-02 22:55:30

ExpandableListView二级分栏详解完美用法的相关文章

[转]Java程序员从笨鸟到菜鸟之(八十三)细谈Spring(十二)OpenSessionInView详解及用法

首先我们来看一下什么是OpenSessionInView?    在hibernate中使用load方法时,并未把数据真正获取时就关闭了session,当我们真正想获取数据时会迫使load加载数据,而此时session已关闭,所以就会出现异常. 比较典型的是在MVC模式中,我们在M层调用持久层获取数据时(持久层用的是load方法加载数据),当这一调用结束时,session随之关闭,而我们希望在V层使用这些数据,这时才会迫使load加载数据,我们就希望这时的session是open着得,这就是所谓

结构体定义 typedef struct 用法详解和用法小结

typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,struct node n;若用typedef,可以这样写,typedef struct node{}NODE; .在申请变量时就可以这样写,NODE n;区别就在于使用时,是否可以省去struct这个关键字. 第三篇:struct和typedef struct 分三块来讲述:1 首先:在C中定义一个结构体

文本处理工具之二 sed命令详解

======博主所学知识来着于恩师马哥的亲授====== 马哥教育"2014夏令营"开始啦!!!马哥教育是目前性价比最高的Linux培训,国内好评度排名第一,并被网友称为Linux界的"黄埔军校",全部课程采用Centos6.5x86_64讲解,经过几期网络班的总结和锤炼,逐渐完善的课程体系,学员学习进度监督和优质的考试系统检验学员掌握程度,活跃的在线答疑环节,名师陪伴,牛人指点,精彩不容错过. 详情猛戳:http://www.magedu.com/ 课程内容:ht

会点网袁帅: O2O实际运用:二维码详解

会点网袁帅: O2O实际运用:二维码详解 [导读]:在O2O实际运作中,小小的二维码有着至关重要的作用.具体有什么作用和怎么来实现二维码的价值呢? 相对于传统模式来说,移动互联网的移动状态和随时随地的特性,让内容商对于消费者的接触越来越全方位,200多年来工业社会形成的基于信息不对称构建的商业模式面临着一个全新的挑战,现在很多企业这2年对O2O的关注和实战越来越多,很多企业如果如果简单在线上搞个网店,线下搞了实体店,在面向消费者的营销.交易和消费体验没有让消费者感觉创意性和立体感,这样的O2O是

MySQL慢查询(二) - pt-query-digest详解慢查询日志 pt-query-digest 慢日志分析

随笔 - 66 文章 - 0 评论 - 19 MySQL慢查询(二) - pt-query-digest详解慢查询日志 一.简介 pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump抓取的MySQL协议数据来进行分析.可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进行分组统计,统计出各查询的执行时间.次数.占比等

Android-- Android事件机制之二:onTouch详解

Android事件机制之二:onTouch详解 在其中对OntouchEvent中的总结中,不是很具体.本文将主要对onTouch进行总结. onTouch是Android系统中整个事件机制的基础.Android中的其他事件,如onClick.onLongClick等都是以onTouch为基础的. onTouch包括从手指按下到离开手机屏幕的整个过程,在微观形式上,具体表现为action_down.action_move和action_up等过程. onTouch两种主要定义形式如下: (1)在

Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程

上一篇文章主要讲述了Android的TouchEvent的分发过程,其中有两个重要的函数:onInterceptTouchEvent和onTouchEvent,这两个函数可被重装以完成特定的逻辑.onInterceptTouchEvent的定义为于ViewGroup中,默认返回值为false,表示不拦截TouchEvent.onTouchEvent的定义位于View中,当ViewGroup要调用onTouchEvent时,会利用super.onTouchEvent.ViewGroup调用onTo

邻接矩阵有向图(二)之 C++详解

本章是通过C++实现邻接矩阵有向图. 目录 1. 邻接矩阵有向图的介绍 2. 邻接矩阵有向图的代码说明 3. 邻接矩阵有向图的完整源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 邻接矩阵有向图的介绍 邻接矩阵有向图是指通过邻接矩阵表示的有向图. 上面的图G2包含了"A,B,C,D,E,F,G"共7个顶点,而且包含了"<A,B>,<B,C>,<B,E>,<

轻量级自动化运维工具ansible之二:playbook详解

在介绍playbook之前,我们先了解一下YAML语言,因为playbook是用YAML语言编写的 一.YAML 1.YAML是一种可读性高的用来表达资料序列的语言,其语法和其他高阶语言类似,并且可以简单表达清单.散列表.标量等数据结构.所有的yaml文件都以"---"开头表示开始一个document,所有的列表元素以"-"开头,键值对用":",后面的空格是必须的下面是一个示例: ---   #打头符可省略 - name: John Smith