2016-04-14 27 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; } 
}