2011-11-01 84 views
4

我一直在使用SeparatedListAdapter這是非常知名的,並且完美的工作,但似乎我不能使用addSection()來添加一個SimpleAdapter,因爲應用程序被終止。我提供了一些代碼來向您展示我正在嘗試執行的操作,並獲得一些指導以解決此問題。請讓我知道,如果你需要的任何其他部分的代碼或任何東西:android連接多個適配器到一個適配器

// Declarations 

private SimpleAdapter _resultsAdapter; 
private ArrayAdapter<String> _adapter; 
private List<Map<String,?>> _resultsList; 
private ArrayList<String> _stringList = new ArrayList<String>(); 

// Much of source code here 

// The following lines work (I can addSection()). 
    _adapter = new ArrayAdapter<String>(this, R.layout.custom_list_item, _stringList); 
    _sla = new SeparatedListAdapter(this); 
    _sla.addSection("Input Data", _adapter); 

// More source code here... 

// The following causes a crash 
_resultsList.add(createItem(resultTitle.toString(), fieldDetails.toString())); // Loading data in a loop (works 100%) 
_resultsAdapter = new SimpleAdapter(CompanyInfoServiceViewActivity.this, _resultsList, R.layout.list_complex, new String[] { ITEM_TITLE, ITEM_CAPTION }, new int[] { R.id.list_complex_title, R.id.list_complex_caption }); 
_sla.addSection("Results", _resultsAdapter); // Crashes here. _sla is not null (see above) 

回答

3

加入這一行:

setListAdapter(_sla); 

線以下:

_sla.addSection("Results", _resultsAdapter); 
17

您可以使用MergeAdapter您列表顯示。這是我的修改和完全測試版本。

/** 
* Adapter that merges multiple child adapters and views into a single 
* contiguous whole. 
* 
* Adapters used as pieces within MergeAdapter must have view type IDs 
* monotonically increasing from 0. Ideally, adapters also have distinct ranges 
* for their row ids, as returned by getItemId(). 
* 
*/ 
public class MergeAdapter extends BaseAdapter implements SectionIndexer { 
    protected ArrayList<ListAdapter> pieces = new ArrayList<ListAdapter>(); 
    protected String noItemsText; 

    /** 
    * Stock constructor, simply chaining to the superclass. 
    */ 
    public MergeAdapter() { 
     super(); 
    } 

    /** 
    * Adds a new adapter to the roster of things to appear in the aggregate 
    * list. 
    * 
    * @param adapter 
    *   Source for row views for this section 
    */ 
    public void addAdapter(ListAdapter adapter) { 
     pieces.add(adapter); 
     adapter.registerDataSetObserver(new CascadeDataSetObserver()); 
    } 

    /** 
    * Get the data item associated with the specified position in the data set. 
    * 
    * @param position 
    *   Position of the item whose data we want 
    */ 
    public Object getItem(int position) { 
     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 
       return (piece.getItem(position)); 
      } 

      position -= size; 
     } 

     return (null); 
    } 

    public void setNoItemsText(String text){ 
     noItemsText = text; 
    } 

    /** 
    * Get the adapter associated with the specified position in the data set. 
    * 
    * @param position 
    *   Position of the item whose adapter we want 
    */ 
    public ListAdapter getAdapter(int position) { 
     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 
       return (piece); 
      } 

      position -= size; 
     } 

     return (null); 
    } 

    /** 
    * How many items are in the data set represented by this Adapter. 
    */ 
    public int getCount() { 
     int total = 0; 

     for (ListAdapter piece : pieces) { 
      total += piece.getCount(); 
     } 

     if(total == 0 && noItemsText != null){ 
      total = 1; 
     } 

     return (total); 
    } 

    /** 
    * Returns the number of types of Views that will be created by getView(). 
    */ 
    @Override 
    public int getViewTypeCount() { 
     int total = 0; 

     for (ListAdapter piece : pieces) { 
      total += piece.getViewTypeCount(); 
     } 

     return (Math.max(total, 1)); // needed for setListAdapter() before 
             // content add' 
    } 

    /** 
    * Get the type of View that will be created by getView() for the specified 
    * item. 
    * 
    * @param position 
    *   Position of the item whose data we want 
    */ 
    @Override 
    public int getItemViewType(int position) { 
     int typeOffset = 0; 
     int result = -1; 

     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 
       result = typeOffset + piece.getItemViewType(position); 
       break; 
      } 

      position -= size; 
      typeOffset += piece.getViewTypeCount(); 
     } 

     return (result); 
    } 

    /** 
    * Are all items in this ListAdapter enabled? If yes it means all items are 
    * selectable and clickable. 
    */ 
    @Override 
    public boolean areAllItemsEnabled() { 
     return (false); 
    } 

    /** 
    * Returns true if the item at the specified position is not a separator. 
    * 
    * @param position 
    *   Position of the item whose data we want 
    */ 
    @Override 
    public boolean isEnabled(int position) { 
     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 
       return (piece.isEnabled(position)); 
      } 

      position -= size; 
     } 

     return (false); 
    } 

    /** 
    * Get a View that displays the data at the specified position in the data 
    * set. 
    * 
    * @param position 
    *   Position of the item whose data we want 
    * @param convertView 
    *   View to recycle, if not null 
    * @param parent 
    *   ViewGroup containing the returned View 
    */ 
    public View getView(int position, View convertView, ViewGroup parent) { 
     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 

       return (piece.getView(position, convertView, parent)); 
      } 

      position -= size; 
     } 

     if(noItemsText != null){ 
      TextView text = new TextView(parent.getContext()); 
      text.setText(noItemsText); 
      return text; 
     } 

     return (null); 
    } 

    /** 
    * Get the row id associated with the specified position in the list. 
    * 
    * @param position 
    *   Position of the item whose data we want 
    */ 
    public long getItemId(int position) { 
     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 
       return (piece.getItemId(position)); 
      } 

      position -= size; 
     } 

     return (-1); 
    } 

    public int getPositionForSection(int section) { 
     int position = 0; 

     for (ListAdapter piece : pieces) { 
      if (piece instanceof SectionIndexer) { 
       Object[] sections = ((SectionIndexer) piece).getSections(); 
       int numSections = 0; 

       if (sections != null) { 
        numSections = sections.length; 
       } 

       if (section < numSections) { 
        return (position + ((SectionIndexer) piece) 
          .getPositionForSection(section)); 
       } else if (sections != null) { 
        section -= numSections; 
       } 
      } 

      position += piece.getCount(); 
     } 

     return (0); 
    } 

    public int getSectionForPosition(int position) { 
     int section = 0; 

     for (ListAdapter piece : pieces) { 
      int size = piece.getCount(); 

      if (position < size) { 
       if (piece instanceof SectionIndexer) { 
        return (section + ((SectionIndexer) piece) 
          .getSectionForPosition(position)); 
       } 

       return (0); 
      } else { 
       if (piece instanceof SectionIndexer) { 
        Object[] sections = ((SectionIndexer) piece).getSections(); 

        if (sections != null) { 
         section += sections.length; 
        } 
       } 
      } 

      position -= size; 
     } 

     return (0); 
    } 

    public Object[] getSections() { 
     ArrayList<Object> sections = new ArrayList<Object>(); 

     for (ListAdapter piece : pieces) { 
      if (piece instanceof SectionIndexer) { 
       Object[] curSections = ((SectionIndexer) piece).getSections(); 

       if (curSections != null) { 
        for (Object section : curSections) { 
         sections.add(section); 
        } 
       } 
      } 
     } 

     if (sections.size() == 0) { 
      return (null); 
     } 

     return (sections.toArray(new Object[0])); 
    } 

    private class CascadeDataSetObserver extends DataSetObserver { 
     @Override 
     public void onChanged() { 
      notifyDataSetChanged(); 
     } 

     @Override 
     public void onInvalidated() { 
      notifyDataSetInvalidated(); 
     } 
    } 
} 

如果需要,還需要ListTitleAdapter在每個適配器之前放置一些標題。

public class ListTitleAdapter extends BaseAdapter { 

     Context context; 
     String text; 
     BaseAdapter parentAdapter; 

     public ListTitleAdapter(Context c, String textToShow) { 
      this(c, textToShow, null); 
    } 

     public ListTitleAdapter(Context c, String textToShow, BaseAdapter dependentAdapter) { 
     super(); 
     context = c; 
     text = textToShow; 

     if(dependentAdapter != null){ 
      parentAdapter = dependentAdapter; 
     } 
    } 

     public int getCount() { 
     if(parentAdapter != null){ 
      if(parentAdapter.getCount() == 0){ 
       return 0; 
      } 
     } 
     return 1; 
    } 

     public Object getItem(int position) { 
     return position; 
    } 

     public long getItemId(int position) { 
     return position; 
    } 

     public View getView(int position, View convertView, ViewGroup parent) { 
     LinearLayout layout = new LinearLayout(context); 
     TextView textView = new TextView(context); 
     textView.setText(text); 

     layout.addView(textView); 

     return layout; 
    } 
    } 

這裏是關於如何使用這兩個類的小例子。

MergeAdapter mergeAdapter = new MergeAdapter(); 

mergeAdapter.addAdapter(new ListTitleAdapter(context, "Title1", someAdapter1)); 
mergeAdapter.addAdapter(someAdapter1); 

mergeAdapter.addAdapter(new ListTitleAdapter(context, "Title2", someAdapter2)); 
mergeAdapter.addAdapter(someAdapter2); 

mergeAdapter.addAdapter(new ListTitleAdapter(context, "Title3", someAdapter3)); 
mergeAdapter.addAdapter(someAdapter3); 

mergeAdapter.setNoItemsText("Nothing to display. This list is empty."); 
((ListView)findViewById(R.id.list)).setAdapter(mergeAdapter); 
+2

關於如何實現項目點擊偵聽器的任何想法? – stephen1706

+0

使用MultiListener。例如: MultiListener ml = new MultiListener(); ml.registerListener(rentClusterManager); ml.registerListener(saleClusterManager); gmap.setOnCameraChangeListener(ml); – KasparTr