【问题标题】:Expandable ListView Grouping Items by Year / Month可扩展的 ListView 按年/月分组项目
【发布时间】:2016-04-14 12:58:01
【问题描述】:

我有一长串从 SQLite 数据库中检索的对象。为简化起见,假设Event 对象具有DateNameLocation 属性。

使用以下列表适配器并从按Date 排序的数据库中获取Events,我可以拥有Events 的时间顺序ListView

public class ImageListButtonListAdapter extends ArrayAdapter<ImageListButtonListItem> {

    public ImageListButtonListAdapter(Context c, List<ImageListButtonListItem> items) {
        super(c, 0, items);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageListButtonView itemView = (ImageListButtonView)convertView;
        if (null == itemView)
            itemView = ImageListButtonView.inflate(parent);
        itemView.setItem(getItem(position));
        return itemView;
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }
}

到目前为止,一切都很好。现在这个列表很长,我想使用ExpandableListView 进一步构建列表,并按月对Event 项目进行分组。我发现创建从BaseExpandableListAdapter 派生的列表适配器的示例通常包括预定义的组和组名。我只有一大组项目,每个项目都包含一个(Joda Time)LocalDate,在此基础上我可以添加一个可用于排序的计算属性YearMonth

我的第一个想法是将整个列表传递给适配器,让适配器确定组,并在创建适配器时将项目分配给组。但我担心以这种方式处理整个列表、创建组并将项目分配给这些组,然后才能显示列表,这在已经对性能敏感的视图中是一个代价高昂的过程。

我可以想象这是一个相当常见的场景,并且有一种更优雅的方法来解决它。最好的方法是什么?

【问题讨论】:

  • 您能否将数据模型的代码也添加到问题中。为什么不能在将数据放入ListView 之前以正确的方式对数据进行排序?
  • 是的,这就是我现在的方法。我让它以某种方式与棒棒糖一起工作,后来。在较旧的设备上,该列表仍然是空的。我会清理一些代码并在短时间内将其添加到问题中。谢谢。
  • 我用当前代码更新了问题。我希望片段能揭示有关数据模型的足够信息——尽量避免发布过多的代码。
  • 在不知道你有多少数据的情况下,我建议你往后退一步,看看你的DatabaseManager,看看你是否可以选择数据并将其正确分组,然后再从数据库。我一直学到的一件事是,无论您可以将什么工作移交给数据库,您都应该这样做,因为数据库引擎在速度方面大多优于 Java 等编程语言。
  • @Darwind 好的,修复了一个不相关的小问题(主要是在我的脑海中:))。该代码实际上独立于 android 版本工作。我可以再次删除附加信息,因为答案并不真正依赖于此(或者它实际上就是答案)。既然您遇到了麻烦,我非常感谢您,并且基本上以您的第一条评论回答了它,您想发布一个正式的答案,以便我给予信任吗?

标签: android sqlite listview expandablelistview


【解决方案1】:

只是为了添加一个答案。

我建议不要在从数据库中获取数据后尝试对数据进行排序,而是通过更改查询数据库的方式来正确地对数据进行分组。

希望这会有所帮助:-)

【讨论】:

  • 好的,谢谢。您的第一条评论解决了功能问题。实际上,ExpandableListView 不包括按给定标准对项目进行分组的“智能”。因此,您需要“手动”将数据分组为带有标题的部分。这就是我需要知道的。性能还可以,并且可以进行一些改进:1.处理DatabaseManager中的分组和2.(如您所建议的)使用智能查询对其进行分组。现在在query.1 之上的整个数据集有两个额外的迭代。很容易做到。 2. 可能是另一个问题的主题。
【解决方案2】:

Darwind 的 cmets and answer 原则性地回答了这个问题。对于任何对代码感兴趣的人,我添加了这个答案。

在创建ListView 之前准备组和孩子是正确的方法。正如达尔文的回答中所指出的那样,通过从数据库中检索数据的方式(此处不包括),可能会获得额外的性能提升。现在代码如下:

public class EventsListFragment extends ExpandableListFragment{

    (...)

    public void onResume() {
        super.onResume();

        dbManager = new DatabaseManager(getActivity());
        mEvents = dbManager.GetEvents();

        mItems.clear();
        mGroups.clear();
        mChildGroups.clear();

        ArrayList<ImageListButtonListItem> childGroup = new ArrayList<>();

        for (int i = mEvents.size()-1; i >= 0; i--) {

            LocalDate date = mEvents.get(i).getDate();
            DateTimeFormatter dtf = DateTimeFormat.longDate();
            String date =  dtf.print(date);
            String name = mEvents.get(i).getEventName();
            String location = mEvents.get(i).getLocation();
            String imagePath = (...)
            ImageListButtonListItem item = new ImageListButtonListItem(date, name, location, imagePath);

            // List category (sorted by months).
            YearMonth yearMonth = new YearMonth(date.getYear(), date.getMonthOfYear());

            if(mGroups.isEmpty()) {
                mGroups.add(yearMonth);
            } else if(!mGroups.contains(yearMonth)) {
                mChildGroups.add(childGroup);
                mGroups.add(yearMonth);
                childGroup = new ArrayList<>();
            }
            childGroup.add(item);
        }
        if (!childGroup.isEmpty()) {
            mChildGroups.add(childGroup);
        }

        mAdapter.notifyDataSetChanged();
    }

    (...)
}

-

public class MonthExpandableImageListButtonListAdapter extends BaseExpandableListAdapter {

    private Context mContext;
    private List<Object> mChildGroups;
    private List<YearMonth> mGroups;
    public LayoutInflater mInflater;
    public Activity mActivity;

    public MonthExpandableImageListButtonListAdapter(Context context, List<Object> childGroups, List<YearMonth> groups) {
        mContext = context;
        mChildGroups = childGroups;
        mGroups = groups;
    }
    public void setInflater(LayoutInflater inflater, Activity act) {
        mInflater = inflater;
        mActivity = act;
    }
    @Override
    public int getGroupCount() { return mGroups.size(); }

    @Override
    public int getChildrenCount(int groupPosition) { return  ((ArrayList<Object>)mChildGroups.get(groupPosition)).size(); }

    @Override
    public Object getGroup(int groupPosition) { return null; }

    @Override
    public Object getChild(int groupPosition, int childPosition) { return null; }

    @Override
    public long getGroupId(int groupPosition) { return 0; }

    @Override
    public long getChildId(int groupPosition, int childPosition) { return 0; }

    @Override
    public boolean hasStableIds() { return false; }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.view_month_expandable_list_header, null);
            }
            ((CheckedTextView) convertView).setText(mGroups.get(groupPosition).toString());
            ((CheckedTextView) convertView).setChecked(isExpanded);
            return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ImageListButtonView itemView = (ImageListButtonView)convertView;
        if (null == itemView)
            itemView = ImageListButtonView.inflate(parent);
        itemView.setItem(((ArrayList<ImageListButtonListItem>) mChildGroups.get(groupPosition)).get(childPosition));
        return itemView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) { return false; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2017-03-24
    相关资源
    最近更新 更多