2016-04-14 57 views
1

我有一长串从SQLite数据库检索的对象。为了简化,我们假设一个Event对象具有属性Date,NameLocation可扩展ListView按年/月分组项目

我可以使用下面的列表适配器和从Date分类数据库中获取Event秒的时间EventListView秒。

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派生的列表适配器的示例通常包括预定义的组和名称。我只有一大组物品,每个物品都含有(乔达时间)LocalDate,基于此我可以添加可用于排序的计算属性YearMonth

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

我可以想象这是一个相当普遍的情况,并且有一个更加优雅的方法来解决它。最好的方法是什么?

+1

你能添加代码为您的数据模型到的问题也。为什么不能在将数据放入ListView之前以正确的方式排序数据? – Darwind

+0

是的,那是我现在的做法。我用棒棒糖和后来的某种方式开始工作。在旧设备上,列表仍然是空的。我将清理一些代码,并在短时间内将其添加到问题中。谢谢。 – jerry

+0

我用当前的代码更新了问题。我希望这个片段能够显示出足够的关于数据模型的信息 - 尽量避免发布过多的代码。 – jerry

回答

1

只需添加一个答案。

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

希望这有助于:-)

+0

是的,谢谢。功能性问题已由您的第一条评论解决。实际上,'ExpandableListView'不包含按给定条件对项目进行分组的“智能”。所以你需要“手动”将数据分组到标题部分。这是我需要知道的。性能是可以的,并且可以做一些改进:1.处理'DatabaseManager'中的分组和2.(如你所建议的)使用智能查询对其进行分组。现在,在查询顶部的整个数据集上还有两个额外的迭代。很容易完成。 2.可能会受到另一个问题的影响。 – jerry

1

Darwind的意见,并回答回答原则上的问题。对于任何对代码感兴趣的人,我都会添加此答案。

在创建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; } 
}