使用过手机QQ的人都知道,那种可以展开并且合并的想过的确很不错。之前做过列表显示绝大部分都是使用的ListView。虽然可以实现列表的展示,这种方法不是很简单也很繁琐,因此在某些情况下,我们还是希望用到可以分组并实现收缩的列表。值得庆幸的是Android为用户提供了这么一个控件 ExpandableListView。
今天研究了一下这个的用法,也参考了一些资料动手写了一个小demo,实现了基本的功能,但界面优化方面做得还不够好,有待改进。
http://www.cnblogs.com/over140/archive/2011/03/18/1987666.html 这个中文api不错。
运行结果如图:
首先是activity_main.xml 相对布局中嵌套线性布局
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:background="@drawable/background"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/linear"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:orientation="horizontal"
android:background="#00AAFF" >
<ImageView
android:id="@+id/img"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/img_1" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="USER[在线]" />
</LinearLayout>
<ExpandableListView
android:id="@+id/expandableListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/linear" >
</ExpandableListView>
</RelativeLayout>
listview_group_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/listview_image"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="@drawable/right" />
<TextView
android:id="@+id/listview_group_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/listview_image"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/listview_image"
android:text="分组名称"
android:textColor="#000000" />
<TextView
android:id="@+id/listview_group_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:text="[10/10]"
android:textColor="#000000" />
</RelativeLayout>
然后是子菜单里面的布局 listview_child_item.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="40dip" >
<ImageView
android:id="@+id/listview_child_img"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:src="@drawable/img_1" />
<TextView
android:id="@+id/listview_child_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/listview_child_img"
android:text="昵称"
android:textSize="16sp" />
<TextView
android:id="@+id/listview_child_trends"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/listview_child_name"
android:layout_alignParentBottom="true"
android:text="该好友暂时没有新动态"
android:textSize="12sp" />
</RelativeLayout>
接下来 开始进行编写代码。
MainActivity.java
package com.demo.qqlistpro;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.Toast;
public class MainActivity extends Activity {
ExpandableListView expandableListView = null;
// 群组名称
private String[] group = new String[] { "在线好友", "我的好友", "哥们" };
// 好友名称
private String[][] users = new String[][] {
{ "好友1", "好友2", "好友3", "好友4" },
{ "好友5", "好友6", "好友7", "好友8", "好友9", "好友10", "好友11", "好友12",
"好友13", "好友14" },
{ "好友15", "好友16", "好友17", "好友18", "好友19", "好友20" } };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置无标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
// 去除列表前自带的箭头
expandableListView.setGroupIndicator(null);
// 配置适配器
ExpandableListAdapter adapter = new QqAdapter(this, group, users);
expandableListView.setAdapter(adapter);
// 设置打开第一组成员(必须在设置适配器之后)
expandableListView.expandGroup(0);
// 分组展开
expandableListView
.setOnGroupExpandListener(new OnGroupExpandListener() {
@Override
public void onGroupExpand(int arg0) {
Toast.makeText(MainActivity.this, "分组展开",
Toast.LENGTH_SHORT).show();
}
});
// 分组合并
expandableListView
.setOnGroupCollapseListener(new OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int arg0) {
Toast.makeText(MainActivity.this, "分组合并",
Toast.LENGTH_SHORT).show();
}
});
// 子菜单
expandableListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView arg0, View arg1,
int groupPosition, int childPosition, long arg4) {
new AlertDialog.Builder(MainActivity.this)
.setIcon(R.drawable.img_1)
.setMessage(
group[groupPosition] + " : "
+ users[groupPosition][childPosition])
.setTitle("用户信息").show();
return false;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
详细代码如下
QqAdapter.java
/**
*
*/
package com.demo.qqlistpro;
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;
/**
* @author Administrator
*
*/
public class QqAdapter extends BaseExpandableListAdapter {
private String[] group = null;
private String[][] users = null;
private Context context = null;
private LayoutInflater inflater = null;
public QqAdapter(Context context, String[] group, String[][] users) {
this.group = group;
this.context = context;
inflater = LayoutInflater.from(context);
this.users = users;
}
/**
* 取得子菜单内容
*/
@Override
public Object getChild(int arg0, int arg1) {
return users[arg0][arg1];
}
/**
* 取得子菜单ID
*/
@Override
public long getChildId(int arg0, int arg1) {
return arg1;
}
/**
* 设置子菜单列表详情
*/
@Override
public View getChildView(int groupPosition, int childPosition,
boolean arg2, View convertView, ViewGroup arg4) {
// 配置适配器
convertView = inflater.inflate(R.layout.listview_child_item, null);
// 取得组件
TextView textView = (TextView) convertView
.findViewById(R.id.listview_child_name);
// 设置组件内容
textView.setText(getChild(groupPosition, childPosition).toString());
return convertView;
}
/**
* 根据组ID取得子菜单个数
*/
@Override
public int getChildrenCount(int groupPosition) {
return users[groupPosition].length;
}
/**
* 取得分组情况
*/
@Override
public Object getGroup(int groupPosition) {
return group[groupPosition];
}
/**
* 取得分组个数
*/
@Override
public int getGroupCount() {
return group.length;
}
/**
* 取得分组ID
*/
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
/**
* 设置分组详情
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup arg3) {
// 配置适配器
convertView = inflater.inflate(R.layout.listview_group_item, null);
TextView textView = (TextView) convertView
.findViewById(R.id.listview_group_name);
textView.setText(getGroup(groupPosition).toString());
// 设置每组人数
TextView tv = (TextView) convertView
.findViewById(R.id.listview_group_num);
tv.setText("[" + getChildrenCount(groupPosition) + "/"
+ getChildrenCount(groupPosition) + "]");
// 设置图片
ImageView imageView = (ImageView) convertView
.findViewById(R.id.listview_image);
imageView.setImageResource(R.drawable.right);
// 如果打开菜单
if (isExpanded) {
imageView.setImageResource(R.drawable.down);
}
return convertView;
}
/**
* 组和子元素是否持有稳定的ID
*/
@Override
public boolean hasStableIds() {
return true;
}
/**
* 子选项是否可以选择
*/
@Override
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return true;
}
}
由此仿QQ列表已经完成,ExpandableListView得基本使用也基本完成了。运行结果已经在上面贴出。
其中有使用几张图片,可以在网上随便下载几张。名称分别为:background.jpg、down.ico、img_1.ico、right.ico,直接放到res/drawable下即可。