我在 SQLite 表中有以下格式的数据:
id|datetime|col1|col2
1|2013-10-30 23:59:59|aaa|aab
2|2013-10-30 23:59:59|abb|aba
3|2013-10-30 23:59:59|abb|aba
4|2013-10-31 23:59:59|abb|aba
5|2013-10-31 23:59:59|abb|aba
我想实现一个 ExpandableListView
以便数据按 datetime
分组并显示如下:
> 2013-10-30 23:59:59 // Group 1
1|aaa|aab
2|abb|aba
3|abb|aba
> 2013-10-31 23:59:59 // Group 2
4|abb|aba
5|abb|aba
我有一个自定义的 CursorAdapter
,我可以轻松地使用它来填充 ListView
,显示每个项目的日期,但我不知道如何“分组” "数据并将其填充到 ExpandableListView
- 你能给我任何提示吗?
最佳答案
I have a custom CursorAdapter that I can easily use to populate ListView, showing date for every single item but I don't know how to "group" the data and populate it on an ExpandableListView - could you please give me any hints?
这是我目前在我的项目中使用的解决方案:
您不能(不应该)使用 CursorAdapter,因为它不适合您的解决方案。您需要通过从 BaseExpandableListAdapter
扩展来创建和实现自己的适配器
然后因为你想创建“你自己的分组”你需要改变你当前的应用程序逻辑:
- 您需要创建从数据库返回的对象集合(例如 演示我将使用名称 Foo)
解决方案:
因此您的 Foo 对象应该如下所示(根据您的要求,变量名称仅用于解释解决方案的想法):
public class Foo {
private String title;
private List<Data> children;
public void setChildren(List<Data> children) {
this.children = children;
}
}
title 将是您数据库中的日期列,children 将是特定(唯一)日期的列。
由于你的例子:
id|datetime|col1|col2
1|2013-10-30 23:59:59|aaa|aab
2|2013-10-30 23:59:59|abb|aba
3|2013-10-30 23:59:59|abb|aba
4|2013-10-31 23:59:59|abb|aba
5|2013-10-31 23:59:59|abb|aba
一个特定的日期(对象 Foo 的标题属性)有更多关联行,因此将使用 Foo 对象中定义的子集来模拟。
所以现在你需要 在你的 getAll() 方法中(从数据库返回数据的方法,通常类似这样调用)你的 DAO 对象(与数据库通信的对象,它只是术语)创建 Foo这个逻辑中的对象。
由于您需要为每个唯一日期正确初始化子项集合,因此您需要使用两个选择查询。您的第一个选择将返回不同的日期 - 因此,如果您在数据库中有 40 行具有 10 个不同(唯一)日期,那么您的选择将包含具有这些唯一日期的 10 行。
确定。 现在您的 ListView 有了“组”。
现在您需要为每个已创建的“组”创建其子项。所以这里是第二个选择,它将选择所有行,并在正确的条件下为每个“组”分配 Foo 对象自己的子集合。
这是伪代码#1:
String query = "select * from YourTable";
Cursor c = db.rawQuery(query, null);
List<Data> childen = new ArrayList<Data>();
if (c != null && c.moveToFirst()) {
for (Foo item: collection) {
// search proper child for current item
do {
// if current row date value equals with current item datetime
if (item.getTitle().equals(c.getString(2))) {
children.add(new Data(column3, column4)); // fetch data from columns
}
} while (c.moveToNext());
// assign created children into current item
item.setChildren(children);
// reset List that will be used for next item
children = null;
children = new ArrayList<Data>();
// reset Cursor and move it to first row again
c.moveToFirst();
}
}
// finally close Cursor and database
现在您的集合已“分组”,现在剩下的工作在您实现的 ListAdapter 上 - 这并不棘手。
您只需要正确实现 getGroupView() 和 getChildView() 方法即可。
在 “组方法” 中,您将使用 Foo 对象集合中的标题扩充和初始化行。这些行将成为 ListView 中的组。
在 “子方法” 中,您将做同样的事情,但您不会膨胀集合中的标题,而是膨胀集合中当前 Foo 对象的子对象。这些行将成为一个特定组的子行。
注意事项:
由于#1。我出于演示目的简化了源代码。但是“在行动中”你可以改变一些事情:
获取第二列通常不是
c.getString(2)
建议使用列名,所以你应该使用c.getColumnIndex("columnName")
代替。将源代码包装到 try-finally block 中是一种很好的做法 finnaly 阻止关闭并释放使用过的资源,例如游标和 数据库。
在示例中,与其“重用”相同的子集合,不如 您可以在 Foo 类中创建公共(public)方法,将项目添加到 直接收集(代码 fragment #2)。
代码 fragment #2:
public class Foo {
private String title;
private List<Data> children = new ArrayList<Data>();
public void addChild(Data child) {
this.children.add(child);
}
...
}
总结:
希望您能理解我(我试图以尽可能简单的方式解释事情,不幸的是,面对面的个人交流是最好的,但我们无法使用此解决方案)并且我希望我能帮助您解决您的问题问题。
关于android - 在 ExpandableListView 上分组数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20349069/