2016-04-14 28 views
1

SQLite veritabanından aldığım uzun bir nesne listesi var. Basitleştirme için, bir Event nesnesinin Date, Name ve Location özelliklerine sahip olduğunu varsayalım.Genişletilebilir ListView Öğeleri Gruplara Göre Ay/Ay

Ben kronolojik ListViewEvent lerini Aşağıdaki liste adaptörü kullanarak ve Date göre sınıflandırılmaktadır veritabanından Event s getirilirken olabilir.

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(); 
    } 
} 

Şimdiye kadar çok iyi. Şimdi bu liste çok uzun ve listeyi ExpandableListView kullanarak daha da yapılandırmak ve Event öğelerini ay olarak gruplamak istiyorum. BaseExpandableListAdapter'dan türetilmiş bir liste bağdaştırıcısı oluştururken bulduğum örnekler genellikle önceden tanımlanmış gruplar ve grup adları içeriyordu. Her biri (Joda Time) LocalDate'u içeren büyük bir öğe grubum var. Buna göre, sıralama için kullanılabilen hesaplanmış bir özellik YearMonth ekleyebilirim.

İlk düşüncem, tüm listeyi bağdaştırıcıya iletmek ve bağdaştırıcıların grupları belirlemesine izin vermek ve bağdaştırıcıyı oluşturduktan sonra öğeleri gruplara atamaktı. Ancak, listenin tamamını bu şekilde işlemekten, grupların oluşturulmasından ve liste oluşturulmadan önce bu gruplara öğe atamasından, performansa duyarlı bir görünümde maliyetli bir işlem olacağından korkuyorum.

Bunun oldukça yaygın bir senaryo olduğunu ve bunu çözmek için daha zarif bir yol olduğunu hayal edebiliyorum. En iyi yaklaşım ne olurdu? Bir yanıt eklemek için

+1

da gündeme sizin datamodel için kod eklemek olabilir. Verilerinizi "ListView" 'a koymadan önce neden doğru bir şekilde sipariş veremiyorsunuz? – Darwind

+0

Evet, şimdi benim yaklaşımım buydu. Ve bir şekilde Lollipop'la ve daha sonra çalışmam lazım. Eski cihazlarda liste hala boş. Bazı kodları temizlerim ve kısa bir süre içinde soruyu ekleyeceğim. Teşekkürler. – jerry

+0

Soruyu mevcut kodla güncelledim. Parçanın veri modeli hakkında - aşırı miktarda kod göndermekten kaçınmaya çalışarak - yeterli bilgiyi ortaya çıkarmasını umuyorum. – jerry

cevap

1

. Veritabanından alındıktan sonra veri siparişi vermek yerine, veritabanını sorgulama şeklinizi değiştirerek verileri doğru şekilde gruplandırmanızı öneririz.

Umut bu

+0

Evet, teşekkürler. İşlevsel sorun ilk yorumunuzla çözüldü. Gerçekten de, 'ExpandableListView', belirli bir kriterle öğeleri gruplandırmak için "İstihbarat" ı içermez. Bu nedenle, verileri "elle", başlıklarla bölümler halinde gruplandırmanız gerekir. Bilmem gereken şey buydu. Performans tamamdır ve yapılabilecek birkaç iyileştirme vardır: 1. "DatabaseManager" içinde gruplandırmayı ve 2. (önerdiğiniz gibi) gruplandırmak için akıllı sorguları kullanın. Şimdi, tüm veri kümesi üzerinde sorgulamanın üstünde iki ek iterasyon var.1. kolayca yapılır. 2. başka bir soruya konu olabilir. – jerry

1

Darwind yorumları, cevap prensipte soruyu yanıtladı :-) yardımcı olur. Kodla ilgilenen herkes için bu cevabı ekliyorum.

Grupları ve çocukları ListView oluşturmadan önce hazırlamak doğru bir yaklaşımdır. Darwin'in cevabında belirtildiği gibi, veri tabanından elde edilen verilerle (burada yer almayan) ek performans artışı sağlanabilir. şöyle Kod şimdi:

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; } 
} 
İlgili konular