自定义ExpandableListView

首先ExpandableListView是干嘛用的?什么地方用到ExpandableListView?

1.用途:有时候我们项目里面可能需要二级列表,当然大家可能想到很多种方式,组合布局、嵌套List等等,其实这些都比较麻烦,为了节省大家时间,所以这里就使用ExpandableListView

所以ExpandableListView组件是android中一个比较常用的组件,大多数会使用系统自带的ExpandableListView来实现,但是想要把ExpandableListView设计成自己想要的样式还需要花费一定的时间,这里自定义一个ExpandableListView来实现如下图的效果:
这里写图片描述

这里组可以点击收缩,展示二级的条目

闲话就不多扯了直接上代码:
BoyMainActivity.java(这里调用)

package com.example.boy.testexpandablelistview;

import android.app.Activity;
import android.os.Bundle;

import com.example.boy.testexpandablelistview.view.MyExpandableListView;
import com.example.boy.testexpandablelistview.view.MyExpandableListViewAdapter;

/**
 * Created by boy on 2016/11/2.
 */

public class BoyMainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        MyExpandableListView myExpandableListView = (MyExpandableListView) findViewById(R.id.my_expandablelist);
        MyExpandableListViewAdapter adapter = new MyExpandableListViewAdapter(this);
        myExpandableListView.setAdapter(adapter);

    }
}

自定义的MyExpandableListView
MyExpandableListView.java

package com.example.boy.testexpandablelistview.view;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;

/**
 * Created by boy on 2016/11/2.
 */

public class MyExpandableListView extends ExpandableListView implements ExpandableListView.OnChildClickListener, ExpandableListView.OnGroupClickListener {


    String[] group_items = {"第一组", "第二组", "第三组", "第四组", "第五组"};
    String[][] child_items = {{"这是第一条", "这是第二条"}, {"这是第一条", "这是第二条", "这是第三条"}, {"这是第一条"}, {"这是第一条", "这是第二条"}, {"这是第一条", "这是第二条", "这是第三条", "这是第四条"}};

    private Context mContext;
    private MyExpandableListViewAdapter adapter;

    public MyExpandableListView(Context context) {
        super(context);
        this.mContext = context;
        /* 隐藏默认箭头显示 */
        this.setGroupIndicator(null);
        /* 隐藏垂直滚动条 */
        this.setVerticalScrollBarEnabled(false);
        /* 监听child,group点击事件 */
        this.setOnChildClickListener(this);
        this.setOnGroupClickListener(this);

        setCacheColorHint(Color.TRANSPARENT);
        setDividerHeight(0);
        setChildrenDrawnWithCacheEnabled(false);
        setGroupIndicator(null);

        /*隐藏选择的黄色高亮*/
        ColorDrawable drawable_tranparent = new ColorDrawable(Color.TRANSPARENT);
        setSelector(drawable_tranparent);

        /*设置adapter*/
        adapter = new MyExpandableListViewAdapter(mContext, group_items, child_items);
        setAdapter(adapter);


    }

    public MyExpandableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
        Toast.makeText(mContext, "点击了第" + (i + 1) + "组的第" + (i1 + 1) + "条!", Toast.LENGTH_SHORT).show();
        //这里就麻烦各位大神亲自写一个接口去引用了
        return false;
    }

    @Override
    public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
        return false;
    }

}

最后adapter
MyExpandableListViewAdapter.java

package com.example.boy.testexpandablelistview.view;

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

import com.example.boy.testexpandablelistview.R;

/**
 * Created by boy on 2016/11/2.
 */

public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {

    private String[] groupStrings;
    private String[][] itmeString;
    private Context mContext;

    public MyExpandableListViewAdapter(Context mContext){

        String[] group_items = {"第一组", "第二组", "第三组", "第四组", "第五组"};
        String[][] child_items = {{"这是第一条", "这是第二条"}, {"这是第一条", "这是第二条", "这是第三条"}, {"这是第一条"}, {"这是第一条", "这是第二条"}, {"这是第一条", "这是第二条", "这是第三条", "这是第四条"}};

        groupStrings = group_items;
        itmeString = child_items;
        this.mContext = mContext;

    }

    public MyExpandableListViewAdapter(Context mContext, String[] groupStrings,String[][] itmeStrings){
        this.groupStrings = groupStrings;
        this.itmeString = itmeStrings;
        this.mContext = mContext;

    }


    /**
     *  取得分组数.
     *
     * @return 分组数.
     */
    @Override
    public int getGroupCount() {
        return groupStrings.length;
    }

    /**
     * 取得指定分组的子元素数.
     *
     * @param i 要取得子元素个数的分组位置.
     *
     * @return 指定分组的子元素个数.
     */
    @Override
    public int getChildrenCount(int i) {
        return itmeString[i].length;
    }

    @Override
    public Object getGroup(int i) {
        return groupStrings[i];
    }

    /**
     *  取得与指定分组、指定子项目关联的数据.
     *
     * @param i 包含子视图的分组的位置.
     * @param i1 指定的分组中的子视图的位置.
     *
     * @return 与子视图关联的数据.
     */
    @Override
    public Object getChild(int i, int i1) {
        return itmeString[i][i1];
    }

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

    /**
     *  取得给定分组中给定子视图的ID.该组ID必须在组中是唯一的.
     *  必须不同于其他所有ID(分组及子项目的ID).
     *
     * @param i 包含子视图的分组的位置.
     * @param i1 要取得ID的指定的分组中的子视图的位置.
     * @return 与子视图关联的ID
     */
    @Override
    public long getChildId(int i, int i1) {
        return i;
    }

    /**
     * 是否指定分组视图及其子视图的ID对应的后台数据改变也会保持该ID.
     * @return 是否相同的ID总是指向同一个对象.
     */
    @Override
    public boolean hasStableIds() {
        return false;
    }

    /**
     * 取得用于显示给定分组的视图.这个方法仅返回分组的视图对象,
     * 要想获取子元素的视图对象,就需要调用getChildView(int, int, boolean, View, ViewGroup).
     *
     * @param i 决定返回哪个视图的组位置.
     *
     * @param b 该组是展开状态还是收起状态 .
     *
     * @param view 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适
     *             的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.不保证
     *             使用先前由getGroupView(int, boolean,View, ViewGroup)创建的视图.
     *
     * @param viewGroup  该视图最终从属的父视图.
     *
     * @return 指定位置相应的组视图.
     */
    @Override
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        TextView tv_groupName;
        if (view == null) {
            view = LayoutInflater.from(mContext).inflate(R.layout.groupviewlayout, null);
        }
        /*判断是否group张开,来分别设置背景图*/
        if (b){
            view.setBackgroundColor(Color.parseColor("#ff00ff"));
        }else {
            view.setBackgroundColor(Color.parseColor("#666666"));
        }
        tv_groupName = (TextView) view.findViewById(R.id.tv_group_name);
        tv_groupName.setText(groupStrings[i]);

        return view;
    }

    /***
     *
     * 取得显示给定分组给定子位置的数据用的视图.
     *
     * @param i 包含要取得子视图的分组位置.
     *
     * @param i1 分组中子视图(要返回的视图)的位置.
     *
     * @param b 该视图是否为组中的最后一个视图.
     *
     * @param view 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适
     *             的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.
     *             不保证使用先前由getChildView(int, int,boolean, View, ViewGroup)创建的视图.
     *
     * @param viewGroup 该视图最终从属的父视图.
     *
     * @return 指定位置相应的子视图.
     */
    @Override
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        TextView tv_childName;
        if (view == null) {
            view = LayoutInflater.from(mContext).inflate(R.layout.childviewlayout, null);

        }
         /*判断是否是最后一项,最后一项设计其他背景*/
        if (b){
            view.setBackgroundColor(Color.parseColor("#00ff00"));
        }else {
            view.setBackgroundColor(Color.parseColor("#999999"));
        }
        tv_childName = (TextView) view.findViewById(R.id.tv_childname);
        tv_childName.setText(itmeString[i][i1]);
        return view;
    }

    /**
     * 指定位置的子视图是否可选择.
     *
     * @param i 包含要取得子视图的分组位置.
     * @param i1 分组中子视图的位置.
     * @return 是否子视图可选择.
     */
    @Override
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }

    /**
     * 取得一览中可以唯一识别子条目的ID(包括分组ID和子条目ID).
     * 可扩展列表要求每个条目(分组条目和子条目)具有一个可以唯一识
     * 别列表中子条目和分组条目的ID.该方法根据给定子条目ID和分组条目ID返回唯
     * 一识别ID.另外,如果hasStableIds()为真,该函数返回的ID必须是固定不变的.
     *
     * @param groupId 包含子条目ID的分组条目ID.
     * @param childId 子条目的ID.
     * @return
     */
    @Override
    public long getCombinedChildId(long groupId, long childId) {
        return super.getCombinedChildId(groupId, childId);
    }
}

哈哈 注释很清楚 就不多解释了!!!
希望大家多多交流,谢谢
最后附上源码地址:
源码地址,猛击下载

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值