在ExpandableListView上分组数据

 sex丶帆布鞋 发布于 2023-02-13 11:33

我在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- 你能不能给我任何提示?

1 个回答
  • 我有一个自定义的CursorAdapter,我可以轻松地使用它来填充ListView,显示每个项目的日期,但我不知道如何"分组"数据并将其填充到ExpandableListView上 - 你能不能给我任何提示?

    这是我目前在我的项目中使用的解决方案:

    您不能(不应该)使用CursorAdapter,因为它不适合您的解决方案.您需要通过扩展来创建和实现自己的适配器BaseExpandableListAdapter

    然后,由于您要创建"自己的分组",您需要更改当前的应用程序逻辑:

    您需要创建从数据库返回的对象集合(用于演示我将使用名称Foo)

    解:

    所以你的Foo对象应该是这样的(由于你的要求,只创建变量名来解释解决方案的想法)这个:

    public class Foo {
    
       private String title;
       private List<Data> children;
    
       public void setChildren(List<Data> children) {
          this.children = children;
       }
    
    }
    

    其中title将是数据库中的date列,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
    

    一个特定的日期(Object Foo的title属性)具有更多关联的行,因此将使用Foo对象中已定义的子集合来模拟这些行.

    所以现在你需要在你的DAO对象(与数据库通信的对象,这是唯一的术语)的getAll()方法(从数据库中返回通常被称为类似的数据的方法)中创建这个逻辑中的Foo对象.

    由于您需要为每个唯一日期正确初始化子集合,因此您需要使用两个选择查询.您的第一个选择将返回不同的日期 - 因此,如果您在数据库中有40行,其中包含10个不同(唯一)日期,那么您的选择将包含具有这些唯一日期的10行.

    OK.现在,您有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块并在finnaly中封闭并释放已使用的源(如游标和数据库)是一种很好的做法.

    而不是"重用"相同的子集合,例如,您可以在Foo类中创建公共方法,直接将项目添加到集合中(代码#2的片段).

    代码片段#2:

    public class Foo {
    
       private String title;
       private List<Data> children = new ArrayList<Data>();
    
       public void addChild(Data child) {
          this.children.add(child);
       }
       ...
    }
    

    摘要:

    希望你了解我(我试图以尽可能简单的方式解释事情,不幸的是面对面的个人沟通是最好的,但这个解决方案对我们来说不可用)而且我希望我帮助你解决问题.

    2023-02-13 11:34 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有