超詳細實用ExpandableListView教程(有圖有真相)

先上效果圖:
超詳細實用ExpandableListView教程(有圖有真相) - liujianqiao398 - 凌風冷暖
 

看到很多關於ExpandableListView的教程都是用一些簡單的String[]字符串數組數據來填充列表項,這在實際項目運用中並不是很實用,下面容筆者來介紹一下如何高效有序地實用自定義實體類線性表ArrayList<Object>來填充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<int><ContactEntry>
* @author LiuJQ
*
*/
public class ContactEntryGroupArray {
private int[] numberOfEachGroup;
private String[] groupName;
private ArrayList<ContactEntry> contactEntryList;

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

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

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

private void copy(ArrayList<ContactEntry> des, ArrayList<ContactEntry> res, int start, int end){
for(int i=start;i<end;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<ContactEntry> 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);
}



小弟不才,各路大神別噴,菜鳥們若有問題,歡迎跟帖發問,有空我會及時回答,謝謝查看本貼。
本貼原創,轉載請註明出處,謝謝。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章