本節繼續講ExpandableListView的使用,與系列(六)中類似,這裡需要寫一個自定義的適配器類繼承BaseExpandableListAdapter, 並且對QQ聯系人列表進行升級,使之具有對聯系人分類的功能,即可以分成"我的好友","朋友","陌生人"等等類別。如果對第六節的內容給比較熟悉,可以完全根據那個思路構造出自己的適配器類,實際上我在寫這節內容之前並沒有參考網上的資料慢慢摸索出來的。
首先是布局文件,
activity_main.xml 主布局文件
復制代碼
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#00aaff"
tools:context=".MainActivity" >
<TextView
android:id="@+id/myText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="聯系人"
android:textSize="7pt"
android:layout_centerHorizontal="true"
android:textColor="#ffffff"
android:textStyle="bold" />
<ExpandableListView
android:id="@+id/qq_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/myText"
android:divider="#888888"
android:dividerHeight="0.15px"/>
</RelativeLayout>
復制代碼
一級條目的布局文件 layout_group.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="wrap_content"
android:paddingLeft="5dip"
android:orientation="horizontal"
android:background="#eeeeee">
<ImageView
android:id="@+id/groupImage"
android:layout_width="match_parent"
android:layout_height="15dip"
android:layout_weight="1.8"
android:layout_gravity="center" />
<TextView
android:id="@+id/groupName"
android:layout_width="match_parent"
android:layout_height="30dip"
android:layout_weight="1"
android:paddingLeft="15dip"
android:paddingTop="5dip"
android:textSize="7pt"
android:text="fdg" />
<TextView
android:id="@+id/childCount"
android:layout_width="match_parent"
android:layout_height="30dip"
android:layout_weight="1"
android:gravity="right"
android:paddingRight="10dip"
android:paddingTop="5dip"
android:text="ewsf"/>
</LinearLayout>
復制代碼
二級條目的布局文件layout_child.xml
復制代碼
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#efefef" >
<!-- LinerLayout有比較奇怪的性質:當布局中的控件可以超出布局規定的大小 ,所以這裡一行的行寬改成由內部的幾個控件
控制,而LinerLayout的layout_height改成wrap_content .. -->
<ImageButton
android:id="@+id/ct_photo"
android:layout_height="70dip"
android:layout_width="70dip"
android:layout_margin="5dip"/>
<TextView
android:id="@+id/ct_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_toRightOf="@id/ct_photo"
android:layout_alignTop="@id/ct_photo"
android:text="為你我受冷風吹"
android:textSize="8pt"
android:textStyle="bold"
android:maxLength="7"/>
<TextView
android:id="@+id/ct_sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_toRightOf="@id/ct_photo"
android:layout_alignBottom="@id/ct_photo"
android:text="為什麼受傷的總是我"
android:textColor="#888888"/>
<!-- 注意不是layout_padding -->
</RelativeLayout>
復制代碼
下面就是自定義的適配器類,為了和Simple適配器參數相同,這裡采用了類似的構造函數。
復制代碼
package com.example.android_baseexpandablelistview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.*;
import java.util.*;
public class MyAdapter extends BaseExpandableListAdapter{
private Context context=null;
private ArrayList<HashMap<String,Object>> groupData=null;
int groupLayout=0;
private String[] groupFrom=null;
private int[] groupTo=null;
private ArrayList<ArrayList<HashMap<String,Object>>> childData=null;
int childLayout=0;
private String[] childFrom=null;
private int[] childTo=null;
public MyAdapter(Context context, ArrayList<HashMap<String, Object>> groupData,
int groupLayout, String[] groupFrom, int[] groupTo,
ArrayList<ArrayList<HashMap<String, Object>>> childData, int childLayout,
String[] childFrom, int[] childTo) {
super();
this.context = context;
this.groupData = groupData;
this.groupLayout = groupLayout;
this.groupFrom = groupFrom;
this.groupTo = groupTo;
this.childData = childData;
this.childLayout = childLayout;
this.childFrom = childFrom;
this.childTo = childTo;
}
@Override
public Object getChild(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
/**
* position與id一樣,都是從0開始計數的,
* 這裡返回的id也是從0開始計數的
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
long id=0;
for(int i=0;i<groupPosition; i++){
id+=childData.size();
}
id+=childPosition;
return id;
}
/**ChildViewHolder內部類**/
class ChildViewHolder{
ImageButton userImage=null;
TextView userName=null;
TextView userSign=null;
}
/**頭像點擊事件監聽類**/
class ImageClickListener implements OnClickListener{
ChildViewHolder holder=null;
public ImageClickListener(ChildViewHolder holder){
this.holder=holder;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, holder.userName.getText()+" is clicked", Toast.LENGTH_SHORT).show();
}
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
/**
* 這裡isLastChild目前沒用到,如果出現異常再說
*/
ChildViewHolder holder=null;
if(convertView==null){
convertView= LayoutInflater.from(context).inflate(childLayout,null);
//感覺這裡需要把root設置成ViewGroup 對象
/**
* ERROR!!這裡不能把null換成parent,否則會出現異常退出,原因不太確定,可能是inflate方法獲得的這個item的View
* 並不屬於某個控件組,所以使用默認值null即可
*/
holder=new ChildViewHolder();
holder.userImage=(ImageButton)convertView.findViewById(childTo[0]);
holder.userName=(TextView)convertView.findViewById(childTo[1]);
holder.userSign=(TextView)convertView.findViewById(childTo[2]);
convertView.setTag(holder);
}
else{
holder=(ChildViewHolder)convertView.getTag();
}
holder.userImage.setBackgroundResource((Integer)(childData.get(groupPosition).get(childPosition).get(childFrom[0])));
holder.userName.setText(childData.get(groupPosition).get(childPosition).get(childFrom[1]).toString());
holder.userSign.setText(childData.get(groupPosition).get(childPosition).get(childFrom[2]).toString());
holder.userImage.setOnClickListener(new ImageClickListener(holder));
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return childData.get(groupPosition).size();
}
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groupData.size();
}
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
class GroupViewHolder{
ImageView image=null;
TextView groupName=null;
TextView childCount=null;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
GroupViewHolder holder=null;
if(convertView==null){
convertView=LayoutInflater.from(context).inflate(groupLayout, null);
holder=new GroupViewHolder();
holder.image=(ImageView)convertView.findViewById(groupTo[0]);
holder.groupName=(TextView)convertView.findViewById(groupTo[1]);
holder.childCount=(TextView)convertView.findViewById(groupTo[2]);
convertView.setTag(holder);
}
else{
holder=(GroupViewHolder)convertView.getTag();
}
int[] groupIndicator=(int[])groupData.get(groupPosition).get(groupFrom[0]);
holder.image.setBackgroundResource(groupIndicator[isExpanded?1:0]);
holder.groupName.setText(groupData.get(groupPosition).get(groupFrom[1]).toString());
holder.childCount.setText(groupData.get(groupPosition).get(groupFrom[2]).toString());
return convertView;
/**
* 不要在適配器中調用適配器的內部方法,不然會出現奇怪的異常
*
*/
}
@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;
}
}
復制代碼
由上一節的內容可知為適配器添加數據非常麻煩,因此這裡創建了一個 QQ用戶類,用來存放一個QQ用戶的各種信息,然後在MainActivity中設計了一個將新QQ用戶對象添加進List數據鏈表中的方法,見下面:
復制代碼
package com.qqlist.contactor;
public class UserInfo {
public String userName=null;
public String userSign=null;
public int userImage=0;
public String groupInfo=null;
public UserInfo(String userName, String userSign, int userImage,
String groupInfo) {
super();
this.userName = userName;
this.userSign = userSign;
this.userImage = userImage;
this.groupInfo = groupInfo;
}
}
復制代碼
然後是MainActivity
復制代碼
package com.example.android_baseexpandablelistview;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ExpandableListView;
import java.util.*;
import com.qqlist.contactor.UserInfo;
public class MainActivity extends Activity {
int[] photoRes={R.drawable.contact_0,R.drawable.contact_1,R.drawable.contact_2,R.drawable.contact_3};
String[] groupFrom={"groupImage","groupName","childCount"};
int[] groupTo={R.id.groupImage,R.id.groupName,R.id.childCount};
String[] childFrom={"userImage","userName","userSign"};
int[] childTo={R.id.ct_photo,R.id.ct_name,R.id.ct_sign};
ArrayList<HashMap<String,Object>> groupData=null;
ArrayList<ArrayList<HashMap<String,Object>>> childData=null;
int[] groupIndicator={R.drawable.toright,R.drawable.todown};
ExpandableListView list=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
groupData=new ArrayList<HashMap<String,Object>>();
childData=new ArrayList<ArrayList<HashMap<String,Object>>> ();
UserInfo user1=new UserInfo("暗夜之殇","總有一天會尋找到自己的幸福",R.drawable.contact_0,"我的好友");
UserInfo user2=new UserInfo("街角的幸福","有些事終於想開了",R.drawable.contact_1,"我的好友");
UserInfo user3=new UserInfo("憤怒的小胖","誰再叫我小胖我跟誰急!",R.drawable.contact_3,"朋友");
UserInfo user4=new UserInfo("放羊的星星","What ever",R.drawable.contact_2,"陌生人");
addUser(user1);
addUser(user2);
addUser(user3);
addUser(user4);
//不能用HashMap的實參賦給Map形參,只能new一個HashMap對象賦給Map的引用!
MyAdapter adapter=new MyAdapter(this,groupData,R.layout.layout_group,groupFrom,groupTo,childData,R.layout.layout_child,childFrom,childTo );
list=(ExpandableListView)findViewById(R.id.qq_list);
list.setAdapter(adapter);
list.setGroupIndicator(null);
}
protected void addUser(UserInfo user)
{
int i;
for(i=0; i< groupData.size(); i++){
if(groupData.get(i).get("groupName").toString().equals(user.groupInfo)){
break;
}
}
if(i>=groupData.size()){
HashMap<String,Object> map=new HashMap<String,Object>();
map.put("groupImage", groupIndicator);
map.put("groupName",user.groupInfo );
map.put("childCount", 0);
groupData.add(map);
ArrayList<HashMap<String,Object>> list=new ArrayList<HashMap<String,Object>>();
childData.add(list);
}
HashMap<String,Object> userData=new HashMap<String,Object>();
userData.put("userImage",user.userImage );
userData.put("userName", user.userName);
userData.put("userSign", user.userSign);
childData.get(i).add(userData);
Integer count=(Integer)groupData.get(i).get("childCount")+1;
groupData.get(i).put("childCount", count);
}
}
復制代碼