2016-04-14 15 views
1

私はSQLiteデータベースから取得しているオブジェクトのリストが長いです。簡略化のため、EventオブジェクトのプロパティがDate,Name、およびLocationであるとします。Expandable ListView年/月単位で項目をグループ化する

私は、以下のリストアダプタを使用し、DateでソートデータベースからEvent Sを取り出す時系列ListViewEventのSを持つことができます。

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を含んでいる1つの大きなグループのグループを持っています。それに基づいてソートに使用できる計算されたプロパティYearMonthを追加することができます。

私の最初の考えは、リスト全体をアダプターに渡し、アダプターにグループを決定させ、アダプターの作成時にグループに項目を割り当てることでした。しかし、リスト全体をこのように処理すること、グループを作成してリストを表示する前にこれらのグループにアイテムを割り当てることは、すでにパフォーマンスに敏感なビューではコストのかかるプロセスになります。

私はこれがかなり一般的なシナリオであると想像することができ、それを解決するよりエレガントな方法があります。最善のアプローチは何でしょうか?

+1

あなたも質問にあなたのデータモデルのコードを追加することができます。 'ListView'に入れる前に正しい方法でデータを注文できないのですか? – Darwind

+0

はい、それは私のアプローチでした。私はLollipop以降で何とか働くようにしました。古いデバイスでは、リストはまだ空です。私はコードのいくつかをきれいにして、しばらくの間それを質問に追加します。ありがとう。 – jerry

+0

質問を現在のコードで更新しました。私はこの断片がデータモデルに関する十分な情報を明らかにし、過剰な量のコードを投稿するのを避けることを願っています。 – jerry

答えて

1

回答を追加するだけです。

データベースからフェッチした後にデータを並べ替えるのではなく、データベースをクエリする方法を変更して、データを正しくグループ化することをお勧めします。

希望これは

+0

はい、ありがとうございます。機能上の問題は、あなたの最初のコメントによって解決されました。実際、 'ExpandableListView'にはアイテムを所与の基準でグループ化するための「知性」は含まれていません。したがって、ヘッダーを含む部分にデータを「手動で」グループ化する必要があります。それは私が知る必要があったものです。パフォーマンスはOKです。いくつかの改善ができます:1. DatabaseManagerとGroup内のグループ化を扱います(あなたが示唆するように)スマートクエリを使用してグループ化します。今度は、クエリの上にデータセット全体に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; } 
} 
関連する問題