简介:
QQ好友界面利用ExpandableListView显示分组和好友列表,以及分组的点击实现对好友列表的显示。
开发中需要类似布局,将源码和解析探讨如下:
效果图:
实现方式:
S1 写ExpandableListView的布局XML文件
非常简单,只需要ExpandableListView控件即可
写上必要的ID(为了获取控件),设置好背景色,间距色
<?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:orientation="vertical" >
<ExpandableListView
android:id="@+id/personInfoListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/home_item_normal"
android:divider="@color/home_item"
android:dividerHeight="1px" >
</ExpandableListView>
</LinearLayout>
布局效果如下所示:
S2 写父ITEM具体布局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="?android:attr/listPreferredItemHeight"
android:orientation="horizontal" >
<TextView
android:id="@+id/group_name"
android:layout_width="wrap_content"
android:layout_height="45dip"
android:layout_marginLeft="35dip"
android:gravity="center_vertical"
android:singleLine="true"
android:text="test"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/home_item"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/group_count"
android:layout_width="wrap_content"
android:layout_height="45dip"
android:layout_marginLeft="5dip"
android:gravity="center_vertical"
android:singleLine="true"
android:text="test"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/home_item"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
显示效果如图:
S3 写子ITEM具体布局XML
显示每个用户图标、用户名称、用户个性签名
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="64dip"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/img"
android:layout_width="60dip"
android:layout_height="60dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="10dip"
android:layout_gravity="center_vertical" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="0.0dip"
android:gravity="center_vertical"
android:text="test"
android:textSize="15.0sp"
android:textColor="#ffc21513"
android:textStyle="bold"
android:layout_weight="1" />
<TextView
android:id="@+id/item_detail"
android:layout_width="wrap_content"
android:layout_height="0.0dip"
android:gravity="center_vertical"
android:singleLine="true"
android:ellipsize="end"
android:textSize="15.0sp"
android:textColor="#ff666666"
android:textStyle="bold"
android:text="test"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
显示效果如图:
S4 编写用于用户显示的对应实体类
存储每个人的信息进行封装
package com.rxz.util;
public class PersonListItem {
// 图片资源
private int resId;
// 姓名
private String name;
// 个性签名
private String detail;
public PersonListItem(int resId, String name, String detail) {
this.resId = resId;
this.name = name;
this.detail = detail;
}
public void setImageId(int resId) {
this.resId = resId;
}
public int getImageId() {
return resId;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getDetail() {
return detail;
}
public String toString() {
return "Item[" + resId + ", " + name + ", " + detail + "]";
}
}
简单说就是一个基本的JavaBean,包括基本属性和相应的Getter,Setter和构造函数
S5 编写自定义ExpandableListView适配器
关于什么是适配器请自行Google,简单说就是一个 ListView 的功能接口
package com.rxz.util;
import java.util.List;
import com.rxz.expandablelistdemo.R;
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 MyAdapter extends BaseExpandableListAdapter{
private Context mContext = null;
private LayoutInflater mInflater = null;
private List<String> mGroupStrings = null;
private List<List<PersonListItem>> mData = null;
/**
* 构造函数
* @param mContext
* @param mGroupStrings
* @param mData
*/
public MyAdapter(Context mContext, List<String> mGroupStrings,
List<List<PersonListItem>> mData) {
super();
this.mContext = mContext;
this.mGroupStrings = mGroupStrings;
this.mData = mData;
this.mInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return mData.get(groupPosition).size();
}
@Override
public List<PersonListItem> getGroup(int groupPosition) {
// TODO Auto-generated method stub
return mData.get(groupPosition);
}
@Override
public PersonListItem getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return mData.get(groupPosition).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
/**
* 获取父视图,当父视图被加载时调用
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
convertView = mInflater.inflate(R.layout.person_group_item_layout, null);
}
GroupViewHolder holder = new GroupViewHolder();
// 组名
holder.mGroupName = (TextView) convertView.findViewById(R.id.group_name);
holder.mGroupName.setText(mGroupStrings.get(groupPosition));
// 组内人数
holder.mGroupCount = (TextView) convertView.findViewById(R.id.group_count);
holder.mGroupCount.setText("[" + mData.get(groupPosition).size() + "]");
return convertView;
}
/**
* 获取子视图,当子视图加载时会调用
*/
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
convertView = mInflater.inflate(R.layout.person_child_item_layout, null);
}
ChildViewHolder holder = new ChildViewHolder();
// 图标
holder.mIcon = (ImageView) convertView.findViewById(R.id.img);
holder.mIcon.setBackgroundResource(getChild(groupPosition, childPosition).getImageId());
// 用户名
holder.mChildName = (TextView) convertView.findViewById(R.id.item_name);
holder.mChildName.setText(getChild(groupPosition, childPosition).getName());
// 签名
holder.mDetail = (TextView) convertView.findViewById(R.id.item_detail);
holder.mDetail.setText(getChild(groupPosition, childPosition).getDetail());
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
/**
* ViewHolder
* 将控件封装方便操作
* @author Mr-rxz
*
*/
private class GroupViewHolder {
// 显示组名
TextView mGroupName;
// 显示组内成员数量
TextView mGroupCount;
}
private class ChildViewHolder {
// 图标
ImageView mIcon;
// 用户名
TextView mChildName;
// 签名
TextView mDetail;
}
}
S6 最后就是编写界面层Activity了
这里加载了一些假数据,并对用户点击事件做了简单的删除操作
package com.rxz.activity;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;
import com.rxz.expandablelistdemo.R;
import com.rxz.util.MyAdapter;
import com.rxz.util.PersonListItem;
public class ActivityMain extends Activity implements OnChildClickListener {
private ExpandableListView mListView = null;
// 表格适配器
private MyAdapter mAdapter = null;
// 组内好友
private List<List<PersonListItem>> mData = new ArrayList<List<PersonListItem>>();
// 分组名字
private List<String> GroupName = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 初始化数据
modifyData();
// 隐藏标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 加载布局
setContentView(R.layout.main_activity);
// 获取控件
mListView = (ExpandableListView) findViewById(R.id.personInfoListView);
// 绑定监听事件
mListView.setOnChildClickListener(this);
// 设置 Item 格式
mListView.setGroupIndicator(getResources().getDrawable(
R.drawable.expander_floder));
// 设置 ListView点击适配器
mAdapter = new MyAdapter(this.getApplicationContext(), GroupName, mData);
mListView.setAdapter(mAdapter);
mListView
.setDescendantFocusability(ExpandableListView.FOCUS_AFTER_DESCENDANTS);
}
/**
* 虚拟数据
*/
private void modifyData() {
GroupName.add("我的好友");
GroupName.add("陌生人");
GroupName.add("黑名单");
List<PersonListItem> itemList = new ArrayList<PersonListItem>();
itemList.add(new PersonListItem(R.drawable.head_pic1, "贝贝", "北京我愛你"));
itemList.add(new PersonListItem(R.drawable.head_pic2, "晶晶", "水晶之淚"));
itemList.add(new PersonListItem(R.drawable.head_pic3, "欢欢", "開開心心每一天"));
itemList.add(new PersonListItem(R.drawable.head_pic4, "盈盈", "Welcome"));
itemList.add(new PersonListItem(R.drawable.head_pic5, "妮妮", "嘿嘿"));
mData.add(itemList);
List<PersonListItem> itemList2 = new ArrayList<PersonListItem>();
itemList2.add(new PersonListItem(R.drawable.head_pic6, "呵呵", "我恨你"));
mData.add(itemList2);
List<PersonListItem> itemList3 = new ArrayList<PersonListItem>();
mData.add(itemList3);
}
@Override
public boolean onChildClick(ExpandableListView parent, View v,
final int groupPosition, final int childPosition, long id) {
// TODO Auto-generated method stub
PersonListItem item = mAdapter.getChild(groupPosition, childPosition);
new AlertDialog.Builder(this)
.setTitle(item.getName())
.setMessage(item.getDetail())
.setIcon(android.R.drawable.ic_menu_more)
.setPositiveButton("删除好友", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
mData.get(groupPosition).remove(childPosition);
mAdapter.notifyDataSetChanged();
Toast.makeText(ActivityMain.this, "成功删除该数据",
Toast.LENGTH_SHORT).show();
}
})
.setNeutralButton("查看详情", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Toast.makeText(ActivityMain.this, "正在查看详情",
Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton(android.R.string.cancel,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
}).create().show();
return true;
}
}
再简单加一些界面美化...这些不是重点,略过
S7 点击运行,大功告成
源码公布如下: