2010-12-16 74 views
0

當前實現的我的listview根據要顯示的對象的變量顯示不同類別/部分中的數據。僅舉例說明,如果數據集是例如{cat,one,red,five,orange,dog},得到的listview將是{animals:cat,dog},{colors:red,orange},{numbers:one,five}。爲此,我使用的是我在網上找到的'SectionerAdapter'的變體,在我的情況下,這個變體對每個部分都使用自定義的ArrayAdapter <>。此代碼提供的部分看起來像任何Android設備的「設置」應用中的部分。可過濾複雜ListView

現在,我試圖過濾這些結果。如果輸入'O',列表將最終爲:{動物:空},{顏色:橙色},{數字:一}。問題是我沒有得到它與整個列表,但只與其中一個部分。這就是爲什麼我試圖在整個列表中使用另一種方法:ExpandableListView。

有人知道在ExpandableListView中過濾是否可能/容易嗎?你們有什麼我可以用來了解如何去做的例子嗎?

謝謝!

回答

1

我爲我的一個項目做了類似的事情。我不在家,所以很遺憾我沒有代碼示例句柄。以下是我做到了這一點 -

我使用自定義ArrayAdapter <牛逼>作爲基礎爲我SectionArrayAdapter <SectionedListItem>。 SectionedListItem被用作我可能希望在SectionedList中顯示的每個項目的基類。 SectionedListItem定義了一些屬性:

boolean isNewSection; 
String sectionLabel; 

這也可能是一個接口,不需要是類。將它作爲一個類對我的實現有意義。

然後,我將要顯示在項目列表中的項目列表在我應用到適配器之前進行自定義排序。當我對列表進行排序時,我將空SectionedListItems添加到新節開始的索引處,將isNewSection屬性設置爲true。當SectionedArrayAdapter執行渲染時,它會查看isNewSection屬性是否爲true。如果這是真的,我渲染出的部分標題,而不是默認的列表項。

這將給你一個單一的清單,在你的過濾期間使用,而不是一堆不同的清單。但是它確實帶來了自己的挑戰 - 但是,您需要在過濾之後重新對列表進行排序,並且/或者您需要忽略僅用於在過濾期間定義新節的SectionedListItems。

我不是說這是最好的辦法,它只是我想出了:)

+0

這是一個類似的方法,我正在使用。我想我需要再試一次,並在我的代碼中重新考慮一些事情。如果你有機會,看到你的代碼的一部分是很好的。如果你確定,當然:)謝謝! – androidtje 2010-12-17 09:24:41

+0

查看我的回答:) – 2010-12-17 13:16:20

0

請注意,這寫的代碼爲原型的一部分,所以它不是很乾淨或光滑的辦法: )但是,它應該讓你朝着正確的方向前進。我還應該注意到InventoryListItem擴展了我的SectionedListItem類,它包含上面概述的屬性。

/* ------------------------- 
*  Class: InventoryAdapter 
* ------------------------- */ 
private final class InventoryAdapter extends ArrayAdapter<InventoryListItem> implements Filterable { 
     /* ------------------------- 
     *  Fields 
     * ------------------------- */ 
     private ArrayList<InventoryListItem> items; 
     private ArrayList<InventoryListItem> staticItems; 
     private int resource; 
     private InventoryFilter filter = null; 
     /* ------------------------- 
     *  Constructor 
     * ------------------------- */ 
     public InventoryAdapter(Context context, int textViewResourceId, ArrayList<InventoryListItem> objects) { 
       super(context, textViewResourceId, objects); 
       items = objects; 
       resource = textViewResourceId; 
       staticItems = items; 
     } 

     /* ------------------------- 
     *  Private Methods 
     * ------------------------- */ 
     private void addCategorySpan(SpannableString span, int startIndex, int endIndex, final String category) { 
       span.setSpan(new ClickableSpan() { 
         @Override 
         public void onClick(View widget) { 
           String categoryFilter = "cat://" + category; 
           filterList(categoryFilter, true); 
         } 
       }, startIndex, endIndex, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); 
     } 

     /* ------------------------- 
     *  Public Methods 
     * ------------------------- */ 
     // Properties 
     @Override 
     public int getCount() { 
       return items.size(); 
     } 
     @Override 
     public InventoryListItem getItem(int position) { 
       return items.get(position); 
     } 
     @Override 
     public int getPosition(InventoryListItem item) { 
       return items.indexOf(item); 
     } 
     @Override 
     public long getItemId(int position) { 
       return items.get(position).id; 
     } 
     @Override 
     public boolean isEnabled(int position) { 
       return true; 
     } 
     // Methods 
     public Filter getFilter() { 
       if (filter == null) { 
         filter = new InventoryFilter(); 
       } 
       return filter; 
     } 
     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
       LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       View v = null; 

       InventoryListItem item = items.get(position); 
       if (item.startNewSection) { 
         v = inflater.inflate(R.layout.sectioned_list_header, null); 

         TextView sectionText = (TextView)v.findViewById(R.id.list_header_title); 
         sectionText.setText(item.sectionName); 
       } else { 
         v = inflater.inflate(resource, null); 
         TextView nameText = (TextView)v.findViewById(R.id.inventory_list_item_name_text); 
         TextView qtyText = (TextView)v.findViewById(R.id.inventory_list_item_qty_text); 
         TextView brandText = (TextView)v.findViewById(R.id.inventory_list_item_brand_text); 
         final TextView categoryText = (TextView)v.findViewById(R.id.inventory_list_item_category_text); 

         nameText.setText(item.name); 
         String qty = Float.toString(item.remainingAmount) + " " + item.measurementAbbv; 
         qtyText.setText(qty); 
         brandText.setText(item.brand); 

         // Create our list of categories and patterns 
         String categories = ""; 
         for (int i = 0; i <= item.categories.size() - 1; i++) { 
           if (categories.length() == 0) { 
             categories = item.categories.get(i); 
           } else { 
             categories += ", " + item.categories.get(i); 
           } 
         } 
         categoryText.setMovementMethod(LinkMovementMethod.getInstance()); 
         categoryText.setText(categories, BufferType.SPANNABLE); 
         // Now creat our spannable text 
         SpannableString span = (SpannableString)categoryText.getText(); 
         // Create our links and set our text 
         int startIndex = 0; 
         boolean stillLooking = true; 
         while (stillLooking) { 
           int commaIndex = categories.indexOf(", ", startIndex); 
           if (commaIndex >= 0) { 
             final String spanText = categoryText.getText().toString().substring(startIndex, commaIndex); 
             addCategorySpan(span, startIndex, commaIndex, spanText); 
             startIndex = commaIndex + 2; 
           } else { 
             final String spanText = categoryText.getText().toString().substring(startIndex, categoryText.getText().toString().length()); 
             addCategorySpan(span, startIndex, categoryText.getText().toString().length(), spanText); 
             stillLooking = false; 
           } 
         } 
         v.setTag(item.id); 
       } 

       return v; 
     } 

     /* ------------------------- 
     *  Class: InventoryFilter 
     * ------------------------- */ 
     private class InventoryFilter extends Filter { 
       private Object lock = new Object(); 

       /* ------------------------- 
       *  Protected Methods 
       * ------------------------- */ 
       @Override 
       protected FilterResults performFiltering(CharSequence constraint) { 
         FilterResults results = new FilterResults(); 
         if (constraint == null || constraint.length() == 0) { 
           synchronized(lock) { 
             items = staticItems; 
             results.values = items; 
             results.count = items.size(); 
           } 
         } else { 
           String searchString = constraint.toString(); 
           // Do our category search 
           if (searchString.startsWith("cat:")) { 
             String trimmedSearch = searchString.substring(searchString.indexOf("://") + 3); 
             // Do our search 
             ArrayList<InventoryListItem> newItems = new ArrayList<InventoryListItem>(); 
             for (int i = 0; i <= items.size() - 1; i++) { 
               InventoryListItem item = items.get(i); 
               // See if we're a section, and if we have an item under us 
               if (item.startNewSection && i < items.size() - 1) { 
                 InventoryListItem next = items.get(i + 1); 
                 if (next.sectionName == item.sectionName) { 
                   if (!next.startNewSection && next.categories.contains(trimmedSearch)) { 
                     newItems.add(item); 
                   } 
                 } 
               } 
               else if (!item.startNewSection && item.categories.contains(trimmedSearch)) { 
                 newItems.add(item); 
               } 
             } 

             results.values = newItems; 
             results.count = newItems.size(); 
           } 
         } 
         return results; 
       } 
       @SuppressWarnings("unchecked") 
       @Override 
       protected void publishResults(CharSequence constraint, FilterResults results) { 
         //noinspection unchecked 
         items = (ArrayList<InventoryListItem>)results.values; 
         // Let the adapter know about the updated list 
         if (results.count > 0) { 
           notifyDataSetChanged(); 
         } else { 
           notifyDataSetInvalidated(); 
          } 
       } 
     } 
}