大家好,又见面了,我是你们的朋友全栈君。本例说明:
1.实例中表现层与数据处理层分开,代码可复用性强,如果能看懂代码对算法会有提高.
2.组和子条目上”点击”事件处理,能够区分操作的是组还是子条目,并且得到组和子条目的内容.
3.组和子条目上”长按”事件处理,能够区分组和子条目,并且得到组和子条目的内容.
4.自定义条目样式,灵活与数据库中字段绑定.
5.实现对DB的增删改查,并且操作后自动刷新.
6.使用数据库处理框架AHibernate灵活操作sqlite数据库,详见: http://blog.csdn.net/lk_blog/article/details/7455992
效果图:
主要代码:
main.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="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="初始化数据" />
<Button
android:id="@+id/btnClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清空数据" />
<ExpandableListView
android:id="@+id/expList"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
list_group.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/group"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/groupIdTo"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/groupNameTo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10px"
android:paddingLeft="30px"
android:paddingTop="10px"
android:text="No data"
android:textSize="26sp" />
</LinearLayout>
list_child.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/child"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/childIdTo"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/childNameTo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="5px"
android:paddingLeft="50px"
android:paddingTop="5px"
android:text="No data"
android:textSize="20sp" />
</LinearLayout>
GroupChild.java:(用于存放数据库中取出的内容)
package com.tgb.lk.demo.util;
public class GroupChild {
public String groupId;
public String groupName;
public String childId;
public String childName;
public GroupChild() {
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getChildId() {
return childId;
}
public void setChildId(String childId) {
this.childId = childId;
}
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
@Override
public String toString() {
return "GroupChild [childId=" + childId + ", childName=" + childName
+ ", groupId=" + groupId + ", groupName=" + groupName + "]";
}
}
GroupChildUtil.java:(这里是构建数据的核心代码,看懂这里对算法有提高哦)
package com.tgb.lk.demo.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.tgb.lk.expandable.R;
import android.content.Context;
import android.text.TextUtils;
import android.widget.SimpleExpandableListAdapter;
public class GroupChildUtil {
// 组布局文件id
private static int groupLayout = R.layout.list_group;
// 内容布局文件id
private static int childLayout = R.layout.list_child;
// 绑定的组Id的名字
public static String groupIdFrom = "group_id";
// 绑定的组name的名字
public static String groupNameFrom = "group_name";
// 绑定的内容Id的名字
public static String childIdFrom = "child_id";
// 绑定的内容Name的名字
public static String childNameFrom = "child_name";
// 组Id绑定控件Id
private static int groupIdTo = R.id.groupIdTo;
// 内容Id绑定控件的Id
private static int childIdTo = R.id.childIdTo;
// 组名称绑定的控件Id
private static int groupNameTo = R.id.groupNameTo;
// 内容Id绑定的控件Id
private static int childNameTo = R.id.childNameTo;
public static SimpleExpandableListAdapter buildAdapter(Context context,
List<GroupChild> groupChildData) {
//定义构建Adpater的组要用的组数据.
List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
//定义构建Adpater的子条目要用的组数据.
List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
//LinkedHashMap会根据添加时顺序存放数据.
Map<Map<String, String>, List<Map<String, String>>> tempMap = new LinkedHashMap<Map<String, String>, List<Map<String, String>>>();
if (groupChildData != null && groupChildData.size() > 0) {
for (int i = 0; i < groupChildData.size(); i++) {
GroupChild gc = groupChildData.get(i);
Map<String, String> groupMap = new HashMap<String, String>();
Map<String, String> childMap = new HashMap<String, String>();
groupMap.put(groupIdFrom, gc.getGroupId());
groupMap.put(groupNameFrom, gc.getGroupName());
if (TextUtils.isEmpty(gc.getChildId())
&& TextUtils.isEmpty(gc.getChildName())) {
childMap = null;
} else {
childMap.put(childIdFrom, gc.getChildId());
childMap.put(childNameFrom, gc.getChildName());
}
//tempMap的key是组,value是组中包含的子条目List.
if (tempMap.containsKey(groupMap)) {
if (childMap != null) {
tempMap.get(groupMap).add(childMap);
}
} else {
List<Map<String, String>> tempList = new ArrayList<Map<String, String>>();
if (childMap != null) {
tempList.add(childMap);
}
tempMap.put(groupMap, tempList);
}
}
}
//循环map,得到最终的group和child.
for (Map<String, String> key : tempMap.keySet()) {
groupData.add(key);
childData.add(tempMap.get(key));
}
SimpleExpandableListAdapter sela = new SimpleExpandableListAdapter(
context, groupData, groupLayout, new String[] { groupIdFrom,
groupNameFrom }, new int[] { groupIdTo, groupNameTo },
childData, childLayout, new String[] { childIdFrom,
childNameFrom }, new int[] { childIdTo, childNameTo });
return sela;
}
}
StudentDaoImpl.java:(数据库中查找到记录并保存为GroupChild对象,用户构建ExpandableListView)
package com.tgb.lk.demo.dao.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.tgb.lk.ahibernate.dao.impl.BaseDaoImpl;
import com.tgb.lk.demo.dao.StudentDao;
import com.tgb.lk.demo.model.Student;
import com.tgb.lk.demo.util.DBHelper;
import com.tgb.lk.demo.util.GroupChild;
import android.content.Context;
//本文数据库处理引用jar包AHibernate处理.
//AHibernate的详细使用教程示例地址: http://blog.csdn.net/lk_blog/article/details/7455992
//AHibernate源码交流地址: http://blog.csdn.net/lk_blog/article/details/7456125
//AHibernate jar包下载及源代码下载地址: http://download.csdn.net/detail/lk_blog/4222048
public class StudentDaoImpl extends BaseDaoImpl<Student> implements StudentDao {
public StudentDaoImpl(Context context) {
super(new DBHelper(context));
}
//查出数据,List中存放GroupChild对象.
public List<GroupChild> getData() {
String sql = "select s._id sid,s.name sname,c._id cid,c.name cname from t_student s "
+ " join t_classes c on s.classesid=c._id";
List<Map<String, String>> list = super.query2MapList(sql, null);
List<GroupChild> retList = new ArrayList<GroupChild>();
for (Map<String, String> map : list) {
GroupChild gc = new GroupChild();
gc.setChildId(map.get("sid"));
gc.setChildName(map.get("sname"));
gc.setGroupId(map.get("cid"));
gc.setGroupName(map.get("cname"));
retList.add(gc);
}
return retList;
}
}
MainActivity.java:
package com.tgb.lk.expandable;
import java.util.HashMap;
import java.util.List;
import com.tgb.lk.demo.dao.ClassesDao;
import com.tgb.lk.demo.dao.StudentDao;
import com.tgb.lk.demo.dao.impl.ClassesDaoImpl;
import com.tgb.lk.demo.dao.impl.StudentDaoImpl;
import com.tgb.lk.demo.model.Classes;
import com.tgb.lk.demo.model.Student;
import com.tgb.lk.demo.util.GroupChild;
import com.tgb.lk.demo.util.GroupChildUtil;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnChildClickListener;
public class MainActivity extends Activity {
private static final int ITEM_MODIFY = 0;
private static final int ITEM_DELETE = 1;
private Button btnAdd = null;
private Button btnClear = null;
private StudentDao studentDao = null;
private ClassesDao classesDao = null;
private ExpandableListView expList = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnAdd = (Button) findViewById(R.id.btnAdd);
btnClear = (Button) findViewById(R.id.btnClear);
expList = (ExpandableListView) findViewById(R.id.expList);
btnAdd.setOnClickListener(listener);
btnClear.setOnClickListener(listener);
// 设置点击子条目时触发事件
expList.setOnChildClickListener(childClickListener);
// 设置长按时的事件
registerForContextMenu(expList);
showData();
}
// 显示数据
public void showData() {
studentDao = (studentDao != null ? studentDao : new StudentDaoImpl(
MainActivity.this));
List<GroupChild> data = studentDao.getData();
SimpleExpandableListAdapter adapter = GroupChildUtil.buildAdapter(this,
data);
expList.setAdapter(adapter);
}
OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
studentDao = (studentDao != null ? studentDao : new StudentDaoImpl(
MainActivity.this));
classesDao = (classesDao != null ? classesDao : new ClassesDaoImpl(
MainActivity.this));
switch (v.getId()) {
case R.id.btnAdd:
toastShow("初始化");
Classes classes = new Classes();
classes.setName("五期提高班");
Long classid1 = classesDao.insert(classes);
Student student1 = new Student();
student1.setName("lk");
student1.setClassesId(classid1.intValue());
studentDao.insert(student1);
Student student2 = new Student();
student2.setName("cls");
student2.setClassesId(classid1.intValue());
studentDao.insert(student2);
Student student3 = new Student();
student3.setName("lb");
student3.setClassesId(classid1.intValue());
studentDao.insert(student3);
Classes classes2 = new Classes();
classes2.setName("六期提高班");
Long classid2 = classesDao.insert(classes2);
Student student4 = new Student();
student4.setName("jzg");
student4.setClassesId(classid2.intValue());
studentDao.insert(student4);
Student student5 = new Student();
student5.setName("lxy");
student5.setClassesId(classid2.intValue());
studentDao.insert(student5);
break;
case R.id.btnClear:
toastShow("清空");
String sql1 = "delete from t_student";
String sql2 = "delete from t_classes";
studentDao.execSql(sql1, null);
classesDao.execSql(sql2, null);
break;
default:
break;
}
showData();
}
};
// 封装Toast,一方面调用简单,另一方面调整显示时间只要改此一个地方即可.
public void toastShow(String text) {
Toast.makeText(MainActivity.this, text, 3000).show();
}
// 长按出现的菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.setHeaderTitle("请选择操作");
menu.add(0, ITEM_MODIFY, 0, "编辑");
menu.add(0, ITEM_DELETE, 1, "删除");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item
.getMenuInfo();
int type = ExpandableListView
.getPackedPositionType(info.packedPosition);
// 子条目
if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
String childId = ((TextView) info.targetView
.findViewById(R.id.childIdTo)).getText().toString().trim();
if (TextUtils.isEmpty(childId) || "0".equals(childId)) {
toastShow("childId为空,不可编辑和删除!");
return false;
}
String childName = ((TextView) info.targetView
.findViewById(R.id.childNameTo)).getText().toString()
.trim();
studentDao = (studentDao != null ? studentDao : new StudentDaoImpl(
MainActivity.this));
switch (item.getItemId()) {
case ITEM_MODIFY:
Student student = studentDao.get(Integer.parseInt(childId));
student.setName("李坤");
studentDao.update(student);
toastShow("修改[" + childName + "]");
break;
case ITEM_DELETE:
studentDao.delete(Integer.parseInt(childId));
toastShow("删除[" + childName + "]成功!");
break;
default:
return false;
}
showData();
return true;
// 组
} else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
String groupId = ((TextView) info.targetView
.findViewById(R.id.groupIdTo)).getText().toString().trim();
if (TextUtils.isEmpty(groupId) || "0".equals(groupId)) {
toastShow("groupId为空,不可编辑和删除!");
return false;
}
String groupName = ((TextView) info.targetView
.findViewById(R.id.groupNameTo)).getText().toString()
.trim();
classesDao = (classesDao != null ? classesDao : new ClassesDaoImpl(
MainActivity.this));
switch (item.getItemId()) {
case ITEM_MODIFY:
Classes classes = classesDao.get(Integer.parseInt(groupId));
classes.setName("五期信息技术提高班");
classesDao.update(classes);
toastShow("修改组[" + groupName + "]");
break;
case ITEM_DELETE:
classesDao.delete(Integer.parseInt(groupId));
toastShow("删除组[" + groupName + "]成功!");
break;
default:
return false;
}
showData();
return true;
}
return true;
}
// 子条目上的点击事件
OnChildClickListener childClickListener = new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
String childId = ((TextView) v.findViewById(R.id.childIdTo))
.getText().toString();
String childName = ((TextView) v.findViewById(R.id.childNameTo))
.getText().toString();
HashMap groupMap = (HashMap) expList.getExpandableListAdapter()
.getGroup(groupPosition);
toastShow("学号:" + childId + ";学生姓名:" + childName + ";班号:"
+ groupMap.get(GroupChildUtil.groupIdFrom).toString()
+ ";班名:"
+ groupMap.get(GroupChildUtil.groupNameFrom).toString());
return true;
}
};
}
ExpandableListView实例(一)_数据库增删改查处理和listitem点击长按处理
http://blog.csdn.net/lk_blog/article/details/7562987
ExpandableListView实例(二)_两种方式实现QQ中组后面显示子条目数量效果
http://blog.csdn.net/lk_blog/article/details/7563355
ExpandableListView实例(三)_实现QQ中”未分组”效果和”未分组”不可编辑删除功能
http://blog.csdn.net/lk_blog/article/details/7563371
源代码下载地址: http://download.csdn.net/detail/lk_blog/4299729
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/149676.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...