参考资料:
1.sakurakider的文章安卓的ExpandableListView的使用和优化
2. sunny.day的文章ExpandableListView(可扩展的listView)
效果图
首先是组布局和组子项布局
group_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="20dp"
android:gravity="left"
android:layoutDirection="ltr"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv"
android:layout_width="40dp"
android:layout_margin="10dp"
android:src="@mipmap/ic_user_photo_default"
android:layout_height="40dp" />
<TextView
android:id="@+id/tv"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:text="哈哈哈哈啊哈"
android:layout_height="40dp" />
</LinearLayout>
childs_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="20dp"
android:gravity="left"
android:layoutDirection="ltr"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv"
android:layout_width="40dp"
android:layout_margin="10dp"
android:src="@mipmap/ic_user_photo_default"
android:layout_height="40dp" />
<TextView
android:id="@+id/tv"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:text="哈哈哈哈啊哈"
android:layout_height="40dp" />
</LinearLayout>
然后是activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ExpandableListView
android:layout_width="match_parent"
android:id="@+id/expand_listview"
android:layout_height="match_parent"
android:layoutDirection="rtl">
</ExpandableListView>
</android.support.constraint.ConstraintLayout>
适配器
MyExpandableAdapter.java
package com.example.expandablelistview3;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyExpandableAdapter extends BaseExpandableListAdapter {
private String[] groups;
private String[][] childs;
Context mcotext;
public MyExpandableAdapter(Context mcotext,String[] groups,String[][] childs) {
this.mcotext=mcotext;
this.groups=groups;
this.childs=childs;
}
// 获取分组的个数
@Override
public int getGroupCount() {
return groups.length;
}
//获取指定分组中的子选项的个数
@Override
public int getChildrenCount(int groupPosition) {
return childs[groupPosition].length;
}
//获取指定的分组数据
@Override
public Object getGroup(int groupPosition) {
return groups[groupPosition];
}
//获取指定分组中的指定子选项数据
@Override
public Object getChild(int groupPosition, int childPosition) {
return childs[groupPosition][childPosition];
}
//获取指定分组的ID, 这个ID必须是唯一的
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
//获取子选项的ID, 这个ID必须是唯一的
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
//分组和子选项是否持有稳定的ID, 就是说底层数据的改变会不会影响到它们
@Override
public boolean hasStableIds() {
return false;
}
/**
* 获取显示指定组的视图对象
*
* @param groupPosition 组位置
* @param isExpanded 该组是展开状态还是伸缩状态
* @param convertView 重用已有的视图对象
* @param parent 返回的视图对象始终依附于的视图组
*/
// 获取显示指定分组的视图
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if(convertView==null){
convertView= LayoutInflater.from(mcotext).inflate(R.layout.group_layout,null);
holder=new ViewHolder();
holder.iv= (ImageView) convertView.findViewById(R.id.iv);
holder.tv= (TextView) convertView.findViewById(R.id.tv);
convertView.setTag(holder);
}else{
holder= (ViewHolder) convertView.getTag();
}
holder.tv.setText(groups[groupPosition]);
return convertView;
}
/**
*
* 获取一个视图对象,显示指定组中的指定子元素数据。
*
* @param groupPosition 组位置
* @param childPosition 子元素位置
* @param isLastChild 子元素是否处于组中的最后一个
* @param convertView 重用已有的视图(View)对象
* @param parent 返回的视图(View)对象始终依附于的视图组
* @return
* @see android.widget.ExpandableListAdapter#getChildView(int, int, boolean, android.view.View,
* android.view.ViewGroup)
*/
//取得显示给定分组给定子位置的数据用的视图
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if(convertView==null){
convertView= LayoutInflater.from(mcotext).inflate(R.layout.childs_layout,null);
holder=new ViewHolder();
holder.iv= (ImageView) convertView.findViewById(R.id.iv);
holder.tv= (TextView) convertView.findViewById(R.id.tv);
convertView.setTag(holder);
}else{
holder= (ViewHolder) convertView.getTag();
}
holder.tv.setText(childs[groupPosition][childPosition]);
return convertView;
}
//指定位置上的子元素是否可选中
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
ViewHolder holder;
class ViewHolder{
TextView tv;
ImageView iv;
}
}
MainActivity.java
package com.example.expandablelistview3;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private String[] groups={"好友","同学"};
private String[][] childs={{"Tom","Jerry","Jeck"},{"XY","WX","YH"}};
ExpandableListView ExpandableListView;
MyExpandableAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExpandableListView= (ExpandableListView) findViewById(R.id.expand_listview);
adapter=new MyExpandableAdapter(getBaseContext(),groups,childs);
ExpandableListView.setAdapter(adapter);
//设置子项布局监听
ExpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(MainActivity.this,
"当前位置"+childs[groupPosition][childPosition], Toast.LENGTH_SHORT).show();
return true;
}
});
}
}