ExpandableListView  (二级列表)使用demo

1.先建立两个item布局  分别为groupItem 和 childItem
2.在主函数xml中创建ExpandableListView   该控件在V7包下
3.写Adapter
4.布局代码:

groupItem:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
<TextView
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:id="@+id/group_name"/>
</LinearLayout>

childItem:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
<TextView
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:id="@+id/child_name_second"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:id="@+id/child_sex_second"/>
</LinearLayout>


xml布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
<ExpandableListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/expandablelistview_second"/>
</LinearLayout>


Adapter代码:


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

import com.tianhe.mydemo.second.SecondChildBean;
import com.tianhe.mydemo.second.SecondGroupBean;

import java.util.ArrayList;

/**
 * Created by dllo on 15/12/29.
 * ExpandableListView(二级列表)
 */
public class SecondExpandableBaseAdapter extends BaseExpandableListAdapter {
    //定义二个实体类承载数据
    //一为groupitem,一为childitem
    private ArrayList<SecondGroupBean> groupBeans;
    private ArrayList<SecondChildBean> childBeans;
    private Context context;

    //构造方法,将实体类的值传到主函数中
    public SecondExpandableBaseAdapter(ArrayList<SecondGroupBean> groupBeans, ArrayList<SecondChildBean> childBeans, Context context) {
        this.groupBeans = groupBeans;
        this.childBeans = childBeans;
        this.context = context;
    }

    //item的数量   为groupitem的size
    @Override
    public int getGroupCount() {
        return groupBeans.size();
    }

    /**
     *在ExpandableListView中 继承了BaseExpandableListAdapter之后
     * 会复写是个方法  其中前两个方法的返回值需要填写  其他的方法都不需要更改
     * 其次是 getGroupView和getChildView按照ListView的getView填写
     * 需要两个缓存类
     * 缓存类的通用方法都类似   记住模式
     */
    @Override
    public int getChildrenCount(int groupPosition) {
        return groupPosition;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return null;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return null;
    }

    @Override
    public long getGroupId(int groupPosition) {
        return 0;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHolder groupViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_second_group, parent, false);
            //切记  此处别忘了缓存类的初始化
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.groupName = (TextView) convertView.findViewById(R.id.group_name);
            convertView.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) convertView.getTag();
        }
        groupViewHolder.groupName.setText(groupBeans.get(groupPosition).getName());
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildViewHolder childViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_second_child, parent, false);
            //切记  此处别忘了缓存类的初始化
            childViewHolder = new ChildViewHolder();
            childViewHolder.childNmae = (TextView) convertView.findViewById(R.id.child_name_second);
            childViewHolder.childSex = (TextView) convertView.findViewById(R.id.child_sex_second);
            convertView.setTag(childViewHolder);
        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        childViewHolder.childNmae.setText(childBeans.get(childPosition).getName());
        childViewHolder.childSex.setText(childBeans.get(childPosition).getSex());
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    class GroupViewHolder {
        TextView groupName;
    }

    class ChildViewHolder {
        TextView childNmae, childSex;
    }
}


主函数代码(Fragment中):

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;

import com.tianhe.mydemo.second.SecondChildBean;
import com.tianhe.mydemo.second.SecondGroupBean;

import java.util.ArrayList;

/**
 * Created by dllo on 15/12/29.
 * fragment中为主函数构建ExpandableListView
 * 创建了Fragment生命周期 
 */
public class SecondFragment extends Fragment{
    private Context context;
    private ArrayList<SecondGroupBean> groupBeans;
    private ArrayList<SecondChildBean> childBeans;
    private ExpandableListView mExpandableListView;
    private SecondExpandableBaseAdapter mSecondExpandableBaseAdapter;
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context = context;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mExpandableListView = (ExpandableListView) getActivity().findViewById(R.id.expandablelistview_second);
        groupBeans = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            groupBeans.add(new SecondGroupBean("我是第" + i + "老爹"));
        }
        childBeans = new ArrayList<>();
        for (int j = 0; j < 30; j++) {
            childBeans.add(new SecondChildBean("我是第" + j + "儿子","我是第" + j + "小儿子"));
        }
        mSecondExpandableBaseAdapter = new SecondExpandableBaseAdapter(groupBeans,childBeans,context);
        mExpandableListView.setAdapter(mSecondExpandableBaseAdapter);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_second,null);
        return view;
    }
}

添加数据,删除数据的自定义方法(适配器代码):
//向已有的组加信息
public void addData(String newData,int group,int childPos){
    child.get(group).add(childPos,newData);
    notifyDataSetChanged();
}
//插入新的组并插入信息
public void addData(String groupName,String childData,int groupPos){
    //新的这一组加到groupPos的位置,组名是groupName
    group.add(groupPos,groupName);
    //为这新的一组,创建一个新的集合,装着child的数据
    List<String> newChild = new ArrayList<>();
    //向这个新的集合里添加数据
    newChild.add(childData);
    //将这个新的集合加到指定的组的位置
    child.add(groupPos, newChild);
    //通知适配器,刷新数据
    notifyDataSetChanged();
}

public void delData(int grouppos) {
    //通知adapter,position位置数据被删除
    if (group.size() <= grouppos) {
        return;
    }
    notifyDataSetChanged();
    group.remove(grouppos);

}

主函数代码:

//guroup组添加监听
mExpandableListView.setOnGroupClickListener(this);
//长按监听
mExpandableListView.setOnItemLongClickListener(this);
//子项添加监听
mExpandableListView.setOnChildClickListener(this);
返回false则子项可以打开,返回true可以获取焦点,但是子项不能打开
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
    Toast.makeText(context, "group" + groupPosition, Toast.LENGTH_SHORT).show();
    return false;
}


//长按监听事件中,返回true为正确  若同时有短按监听和长按监听,返回false则都会相应
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    mSecondExpandableBaseAdapter.delData(position);
    return true;
}

@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
    Toast.makeText(context, "child" + childPosition, Toast.LENGTH_SHORT).show();

    return true;
}


demo效果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有时候,使用ListView并不能满足应用程序所需要的功能。有些应用程序需要多组ListView,这时候我们就要使用一种新的控件ExpandableListView——可以扩展的ListView。它的作用就是将ListView进行分组。就好像我们使用QQ的时候,有“我的好友”,“陌生人”,“黑名单”一样,点击一下会扩展开,再点击一下又会收缩回去。 ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项。这些子项来自于与该视图关联的ExpandableListAdapter。 每一个可以扩展的列表项的旁边都有一个指示符(箭头)用来说明该列表项目前的状态(这些状态一般是已经扩展开的列表项,还没有扩展开的列表项,子列表项和最后一个子列表项)。可以使用方法:setChildIndicator(Drawable),setGroupIndicator(Drawable)(或者相应的XML文件的属性) 去设置这些指示符的样式。当然也可以使用默认的指示符。布android.R.layout.simple_expandable_list_item_1,android.R.layout.simple_expandable_list_item_2 和ListView一样,ExpandableListView也是一个需要Adapter作为桥梁来取得数据的控件。一般适用于ExpandableListView的Adapter都要继承BaseExpandableListAdapter这个类,并且必须重载getGroupView和getChildView这两个最为重要的方法。 BaseExpandableListAdapter的主要重载方法如下: public abstract ObjectgetChild (int groupPosition, int childPosition) 取得与指定分组、指定子项目关联的数据. 参数 groupPosition 包含子视图的分组的位置. childPosition 指定的分组中的子视图的位置. 返回 与子视图关联的数据. public abstract long getChildId (int groupPosition, intchildPosition) 取得给定分组中给定子视图的ID. 该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID). 参数 groupPosition 包含子视图的分组的位置. childPosition 要取得ID的指定的分组中的子视图的位置. 返回 与子视图关联的ID. public abstract View getChildView (int groupPosition, intchildPosition, boolean isLastChild, View convertView, ViewGroup parent) 取得显示给定分组给定子位置的数据用的视图. 参数 groupPosition 包含要取得子视图的分组位置. childPosition 分组中子视图(要返回的视图)的位置. isLastChild 该视图是否为组中的最后一个视图. convertView 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.不保证使用先前由 getChildView(int, int,boolean, View, ViewGroup)创建的视图. parent 该视图最终从属的父视图. 返回 指定位置相应的子视图. public abstract int getChildrenCount (int groupPosition) 取得指定分组的子元素数. 参数 groupPosition 要取得子元素个数的分组位置. 返回 指定分组的子元素个数. public abstract long getCombinedChildId (long groupId, long childId) 取得一览中可以唯一识别子条目的 ID(包括分组ID和子条目ID).可扩展列表要求每个条目 (分组条目和子条目)具有一个可以唯一识别列表中子条目和分组条目的ID. 该方法根据给定子条目ID和分组条目ID返回唯一识别ID.另外,如果 hasStableIds() 为真,该函数返回的ID必须是固定不变的. 参数 groupId 包含子条目ID的分组条目ID. childId 子条目的ID. 返回 可以在所有分组条目和子条目中唯一识别该子条目的ID(可能是固定不变

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值