ExpandableListView / ExpandableListActivity
二者关系 和 ListActivity / ListView 是一样的
[代码 步骤]
1. 定义含有ExpandableListView 的布局:main.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:id="@+id/layout"
- >
- <ExpandableListView
- android:id="@+id/expandList"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/layout" > <ExpandableListView android:id="@+id/expandList" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
2. 定义数据结构List<String>, List<List<String>> 分别用于存放 Group / Children 的String
- List<String> group;
- List<List<String>> child;
List<String> group;
List<List<String>> child;
3. 初始化 List<String> List<List<String>> 并插入一些数据
- public void initialData(){
- group = new ArrayList<String>();
- child = new ArrayList<List<String>>();
- addInfo("griffinshi", new String[]{"13776117119","man","Jiangsu"});
- addInfo("lancewu",new String[]{"1321134","man","Taiwan"});
- addInfo("kandyli",new String[]{"12345"});
- }
- public void addInfo(String p,String[] c){
- group.add(p);
- List<String> item = new ArrayList<String>();
- for(int i=0;i<c.length;i++){
- item.add(c[i]);
- }
- child.add(item);
- }
public void initialData(){
group = new ArrayList<String>();
child = new ArrayList<List<String>>();
addInfo("griffinshi", new String[]{"13776117119","man","Jiangsu"});
addInfo("lancewu",new String[]{"1321134","man","Taiwan"});
addInfo("kandyli",new String[]{"12345"});
}
public void addInfo(String p,String[] c){
group.add(p);
List<String> item = new ArrayList<String>();
for(int i=0;i<c.length;i++){
item.add(c[i]);
}
child.add(item);
}
3. 定义BaseExpandableListAdapter 并与List<String> List<List<String>> 数据相适配
- public class InfoDetailsAdapter extends BaseExpandableListAdapter {
- Activity activity;
- public InfoDetailsAdapter(Activity a){
- activity = a;
- }
- //child method stub
- @Override
- public Object getChild(int groupPosition, int childPosition) {
- // TODO Auto-generated method stub
- return child.get(groupPosition).get(childPosition);
- }
- @Override
- public long getChildId(int groupPosition, int childPosition) {
- // TODO Auto-generated method stub
- return childPosition;
- }
- @Override
- public int getChildrenCount(int groupPosition) {
- // TODO Auto-generated method stub
- return child.get(groupPosition).size();
- }
- @Override
- public View getChildView(int groupPosition, int childPosition,
- boolean isLastChild, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- String string = child.get(groupPosition).get(childPosition);
- return getGenericView(string);
- }
- //group method stub
- @Override
- public Object getGroup(int groupPosition) {
- // TODO Auto-generated method stub
- return group.get(groupPosition);
- }
- @Override
- public int getGroupCount() {
- // TODO Auto-generated method stub
- return group.size();
- }
- @Override
- public long getGroupId(int groupPosition) {
- // TODO Auto-generated method stub
- return groupPosition;
- }
- @Override
- public View getGroupView(int groupPosition, boolean isExpanded,
- View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- String string = group.get(groupPosition);
- return getGenericView(string);
- }
- //View stub to create Group/Children 's View
- public TextView getGenericView(String s) {
- // Layout parameters for the ExpandableListView
- AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, 64);
- TextView text = new TextView(activity);
- text.setLayoutParams(lp);
- // Center the text vertically
- text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
- // Set the text starting position
- text.setPadding(36, 0, 0, 0);
- text.setText(s);
- return text;
- }
- @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;
- }
- }
public class InfoDetailsAdapter extends BaseExpandableListAdapter {
Activity activity;
public InfoDetailsAdapter(Activity a){
activity = a;
}
//child method stub
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return child.get(groupPosition).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return child.get(groupPosition).size();
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
String string = child.get(groupPosition).get(childPosition);
return getGenericView(string);
}
//group method stub
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return group.get(groupPosition);
}
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return group.size();
}
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
String string = group.get(groupPosition);
return getGenericView(string);
}
//View stub to create Group/Children 's View
public TextView getGenericView(String s) {
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 64);
TextView text = new TextView(activity);
text.setLayoutParams(lp);
// Center the text vertically
text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
text.setPadding(36, 0, 0, 0);
text.setText(s);
return text;
}
@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;
}
}
4. emulator 运行截图:
5. 下面说一下 数据更新 问题 包括:添加数据 删除数据
* 定义添加数据界面:add.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="姓名:"
- />
- <EditText
- android:id="@+id/add_name"
- android:layout_width="200dip"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="电话:"
- />
- <EditText
- android:id="@+id/add_phone"
- android:layout_width="200dip"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="性别:"
- />
- <EditText
- android:id="@+id/add_sex"
- android:layout_width="200dip"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="住址:"
- />
- <EditText
- android:id="@+id/add_home"
- android:layout_width="200dip"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <Button
- android:id="@+id/add_ok"
- android:layout_width="90dip"
- android:layout_height="wrap_content"
- android:text="OK"
- />
- <Button
- android:id="@+id/add_no"
- android:layout_width="90dip"
- android:layout_height="wrap_content"
- android:text="NO"
- />
- </LinearLayout>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:" /> <EditText android:id="@+id/add_name" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="电话:" /> <EditText android:id="@+id/add_phone" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="性别:" /> <EditText android:id="@+id/add_sex" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="住址:" /> <EditText android:id="@+id/add_home" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/add_ok" android:layout_width="90dip" android:layout_height="wrap_content" android:text="OK" /> <Button android:id="@+id/add_no" android:layout_width="90dip" android:layout_height="wrap_content" android:text="NO" /> </LinearLayout> </LinearLayout>
* add.xml 里 View 的定义:
- public void createDialogAdd(){
- viewAdd = this.getLayoutInflater().inflate(R.layout.add, null);
- dialogAdd = new Dialog(this);
- dialogAdd.setContentView(viewAdd);
- dialogAdd.setTitle("输入新成员信息");
- add_name = (EditText)viewAdd.findViewById(R.id.add_name);
- add_phone = (EditText)viewAdd.findViewById(R.id.add_phone);
- add_sex = (EditText)viewAdd.findViewById(R.id.add_sex);
- add_home = (EditText)viewAdd.findViewById(R.id.add_home);
- add_ok = (Button)viewAdd.findViewById(R.id.add_ok);
- add_no = (Button)viewAdd.findViewById(R.id.add_no);
- add_ok.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- // TODO Auto-generated method stub
- String[] data = {
- add_phone.getText().toString(),
- add_sex.getText().toString(),
- add_home.getText().toString()
- };
- addInfo(add_name.getText().toString(),data);
- dialogAdd.dismiss();
- mAdapter.notifyDataSetChanged();
- }
- });
- add_no.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- // TODO Auto-generated method stub
- dialogAdd.dismiss();
- }
- });
- }
public void createDialogAdd(){ viewAdd = this.getLayoutInflater().inflate(R.layout.add, null); dialogAdd = new Dialog(this); dialogAdd.setContentView(viewAdd); dialogAdd.setTitle("输入新成员信息"); add_name = (EditText)viewAdd.findViewById(R.id.add_name); add_phone = (EditText)viewAdd.findViewById(R.id.add_phone); add_sex = (EditText)viewAdd.findViewById(R.id.add_sex); add_home = (EditText)viewAdd.findViewById(R.id.add_home); add_ok = (Button)viewAdd.findViewById(R.id.add_ok); add_no = (Button)viewAdd.findViewById(R.id.add_no); add_ok.setOnClickListener(new OnClickListener(){ public void onClick(View v) { // TODO Auto-generated method stub String[] data = { add_phone.getText().toString(), add_sex.getText().toString(), add_home.getText().toString() }; addInfo(add_name.getText().toString(),data); dialogAdd.dismiss(); mAdapter.notifyDataSetChanged(); } }); add_no.setOnClickListener(new OnClickListener(){ public void onClick(View v) { // TODO Auto-generated method stub dialogAdd.dismiss(); } }); }
* 运行截图:
* 定义删除数据界面:delete.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="ID:"
- />
- <EditText
- android:id="@+id/delete_id"
- android:layout_width="200dip"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <Button
- android:id="@+id/delete_ok"
- android:layout_width="90dip"
- android:layout_height="wrap_content"
- android:text="OK"
- />
- <Button
- android:id="@+id/delete_no"
- android:layout_width="90dip"
- android:layout_height="wrap_content"
- android:text="NO"
- />
- </LinearLayout>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ID:" /> <EditText android:id="@+id/delete_id" android:layout_width="200dip" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/delete_ok" android:layout_width="90dip" android:layout_height="wrap_content" android:text="OK" /> <Button android:id="@+id/delete_no" android:layout_width="90dip" android:layout_height="wrap_content" android:text="NO" /> </LinearLayout> </LinearLayout>
* delete.xml 里View 定义:
- public void createDialogDelete(){
- viewDelete = this.getLayoutInflater().inflate(R.layout.delete, null);
- dialogDelete = new Dialog(this);
- dialogDelete.setContentView(viewDelete);
- dialogDelete.setTitle("删除指定成员");
- delete_id = (EditText)viewDelete.findViewById(R.id.delete_id);
- delete_ok = (Button)viewDelete.findViewById(R.id.delete_ok);
- delete_no = (Button)viewDelete.findViewById(R.id.delete_no);
- delete_ok.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- // TODO Auto-generated method stub
- String id = delete_id.getText().toString();
- if(! id.equals("")){
- int i = Integer.parseInt(id);
- group.remove(i);
- child.remove(i);
- dialogDelete.dismiss();
- mAdapter.notifyDataSetChanged();
- }
- }
- });
- delete_no.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- // TODO Auto-generated method stub
- dialogDelete.dismiss();
- }
- });
- }
public void createDialogDelete(){
viewDelete = this.getLayoutInflater().inflate(R.layout.delete, null);
dialogDelete = new Dialog(this);
dialogDelete.setContentView(viewDelete);
dialogDelete.setTitle("删除指定成员");
delete_id = (EditText)viewDelete.findViewById(R.id.delete_id);
delete_ok = (Button)viewDelete.findViewById(R.id.delete_ok);
delete_no = (Button)viewDelete.findViewById(R.id.delete_no);
delete_ok.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
String id = delete_id.getText().toString();
if(! id.equals("")){
int i = Integer.parseInt(id);
group.remove(i);
child.remove(i);
dialogDelete.dismiss();
mAdapter.notifyDataSetChanged();
}
}
});
delete_no.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
dialogDelete.dismiss();
}
});
}
* 运行截图:
最后 说一下ExpandableListView的回调函数 用于监听那个id 被expand
- expandList.setOnGroupClickListener(new OnGroupClickListener(){
- @Override
- public boolean onGroupClick(ExpandableListView arg0, View arg1,
- int arg2, long arg3) {
- // TODO Auto-generated method stub
- Toast.makeText(activity,"[Group Click]:"+arg2,Toast.LENGTH_LONG).show();
- return false;
- }
- });
- expandList.setOnChildClickListener(new OnChildClickListener(){
- @Override
- public boolean onChildClick(ExpandableListView arg0, View arg1,
- int arg2, int arg3, long arg4) {
- // TODO Auto-generated method stub
- Toast.makeText(activity,"[Child Click]:"+arg2+":"+arg3,Toast.LENGTH_LONG).show();
- return false;
- }
- });