超详细实用ExpandableListView教程(有图有真相)

先上效果图:
 

看到很多关于ExpandableListView的教程都是用一些简单的String[]字符串数组数据来填充列表项,这在实际项目运用中并不是很实用,下面容笔者来介绍一下如何高效有序地实用自定义实体类线性表ArrayList来填充ExpandableListView的列表项。首先我们可以定义列表项的数据实体类ContactEntry.java如下:
 
   

package com.clicknect.ichat.entry;

import android.graphics.Bitmap;

public class ContactEntry {

private String jid;
private String nickname;
private byte[] avatarByte;
private Bitmap avatarBitmap;
private boolean isOnline;
private String onlineViaResource;

public ContactEntry() {
this.jid = null;
this.nickname = null;
this.avatarByte = null;
this.avatarBitmap = null;
this.isOnline = false;
}

public String getJid() {
return jid;
}

public void setJid(String jid) {
this.jid = jid;
}

public String getNickname() {
return nickname;
}

public void setNickname(String nickname) {
this.nickname = nickname;
}

public byte[] getAvatarByte() {
return avatarByte;
}

public void setAvatarByte(byte[] avatarByte) {
this.avatarByte = avatarByte;
}

public Bitmap getAvatarBitmap() {
return avatarBitmap;
}

public void setAvatarBitmap(Bitmap avatarBitmap) {
this.avatarBitmap = avatarBitmap;
}

public boolean isOnline() {
return isOnline;
}

public void setOnline(boolean isOnline) {
this.isOnline = isOnline;
}

public String getOnlineViaResource() {
return onlineViaResource;
}

public void setOnlineViaResource(String onlineViaResource) {
this.onlineViaResource = onlineViaResource;
}

}



然后我们来自定义一个ContactEntry.java类的二维数组类,解释一下这个所谓的“自定义类的二维数组类”,由于填充ExpandableListView的数据是分组的,我们把不同的组作为“自定义类的二维数组类”的第一维,然后把组中的成员(也就是ContactEntry类)作为第二维。这个“自定义类的二维数组类”ContactEntryGroupArray.java如下:
 
   

package com.clicknect.ichat.helper;

import java.util.ArrayList;
import com.clicknect.ichat.entry.ContactEntry;

/**
* 联系人对象组数组类
* 形如:ArrayList
* @author LiuJQ
*
*/
public class ContactEntryGroupArray {
private int[] numberOfEachGroup;
private String[] groupName;
private ArrayList contactEntryList;

public ContactEntryGroupArray(String[] groupName, int[] numberOfEachGroup, ArrayList contactEntryList){
this.groupName = groupName;
this.numberOfEachGroup = numberOfEachGroup;
this.contactEntryList = contactEntryList;
}

public String getGroupName(int groupID){
return groupID < groupName.length ? groupName[groupID] : null;
}

public ArrayList getGroup(int groupID){
if(!(groupID
return null;
}else{
ArrayList contactGroup = new ArrayList();
int start = 0;
for(int i=0;i
start += numberOfEachGroup[i];
}
int end = start + numberOfEachGroup[groupID];
copy(contactGroup,contactEntryList,start,end);
return contactGroup;
}
}

private void copy(ArrayList des, ArrayList res, int start, int end){
for(int i=start;i
des.add(res.get(i));
}
}

public ContactEntry getContact(int groupID, int groupPosition){
ContactEntry selectedContact = getGroup(groupID).get(groupPosition);
return selectedContact != null ? selectedContact : null;
}

public int getGroupCount(){
return groupName.length;
}
}



最后,我们来继承BaseExpandableListAdapter适配器类实现我们自己的适配器ContactGroupAdapter,有了这个适配器我们就可以很好的填充ExpandableListView组件了。适配器类ContactGroupAdapter实现如下:
 
   

package com.clicknect.ichat.adapter;

import java.util.ArrayList;
import com.clicknect.android.ichat.R;
import com.clicknect.ichat.ChatActivity;
import com.clicknect.ichat.MainActivity;
import com.clicknect.ichat.entry.ContactEntry;
import com.clicknect.ichat.helper.ContactEntryGroupArray;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class ContactGroupAdapter extends BaseExpandableListAdapter {
private ContactEntryGroupArray mContactEntryGroupArray;
private Context mContext;
private LayoutInflater mLayoutInflater;

public ContactGroupAdapter(Context context, ContactEntryGroupArray contactEntryGroupArray){
mContactEntryGroupArray = contactEntryGroupArray;
mContext = context;
mLayoutInflater = LayoutInflater.from(mContext);
}

public void setData(ContactEntryGroupArray contactEntryGroupArray){
mContactEntryGroupArray = contactEntryGroupArray;
}

@Override
public Object getChild(int groupID , int groupPosition ) {
// TODO Auto-generated method stub
return mContactEntryGroupArray.getContact(groupID, groupPosition);
}

@Override
public long getChildId(int groupID, int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}

@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
convertView = mLayoutInflater.inflate(R.layout.contact_listview_child_item, null);
}

final ContactEntry currentContact = mContactEntryGroupArray.getContact(groupPosition, childPosition);

TextView contactName = (TextView)convertView.findViewById(R.id.contact_listview_child_nick);
contactName.setText(currentContact.getNickname());

TextView contactStatus = (TextView)convertView.findViewById(R.id.contact_listview_child_status);
if(currentContact.isOnline()){
contactName.setTextColor(Color.GREEN);
contactStatus.setText("online");
}else{
contactName.setTextColor(Color.BLACK);
contactStatus.setText("offline");
}

return convertView;
}

@Override
public int getChildrenCount(int groupID) {
// TODO Auto-generated method stub
return mContactEntryGroupArray.getGroup(groupID).size();
}

@Override
public ArrayList getGroup(int groupID) {
// TODO Auto-generated method stub
return mContactEntryGroupArray.getGroup(groupID);
}

@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return mContactEntryGroupArray.getGroupCount();
}

@Override
public long getGroupId(int groupID) {
// TODO Auto-generated method stub
return groupID;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
convertView = mLayoutInflater.inflate(R.layout.contact_listview_group_item, null);
}

TextView groupName = (TextView)convertView.findViewById(R.id.contact_listview_group_name);
groupName.setText(mContactEntryGroupArray.getGroupName(groupPosition));

TextView onlineNumber = (TextView)convertView.findViewById(R.id.contact_listview_group_num);
StringBuffer sb = new StringBuffer();
sb.append(getOnlineNumber(groupPosition));
sb.append('/');
sb.append(getChildrenCount(groupPosition));
onlineNumber.setText(sb.toString());
return convertView;
}

private int getOnlineNumber(int groupID){
int numberOfOnlineEntry = 0;
for(ContactEntry contactEntry : getGroup(groupID)){
if(contactEntry.isOnline()){
numberOfOnlineEntry++;
}
}
return numberOfOnlineEntry;
}

@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}

}



好了,一切准备就绪,现在我们要做的就是从布局文件中获取到ExpandableListView组件,然后利用上面适配器类的构造方法设置好数据,接下来系统便会为我们做好图形界面的渲染了:
 
   

public ContactGroupAdapter(Context context, ContactEntryGroupArray contactEntryGroupArray){
mContactEntryGroupArray = contactEntryGroupArray;
mContext = context;
mLayoutInflater = LayoutInflater.from(mContext);
}



小弟不才,各路大神别喷,菜鸟们若有问题,欢迎跟帖发问,有空我会及时回答,谢谢查看本贴。
本贴原创,转载请注明出处,谢谢。

你可能感兴趣的:(Android开发)