首先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);
}
}
哈哈 注释很清楚 就不多解释了!!!
希望大家多多交流,谢谢
最后附上源码地址:
源码地址,猛击下载