2010-12-16 76 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(); 
          } 
       } 
     } 
}