Android conecta múltiples adaptadores a un adaptador

He estado usando SeparatedListAdapter, que es muy conocido y funciona perfectamente, pero parece que no puedo usar addSection () para agregar un SimpleAdapter, porque la aplicación ha finalizado. Proporciono un código para mostrarte lo que trato de hacer y obtener orientación para resolver este problema. Por favor, avíseme si necesita algún otro código o algo:

// Declarations private SimpleAdapter _resultsAdapter; private ArrayAdapter _adapter; private List<Map> _resultsList; private ArrayList _stringList = new ArrayList(); // Much of source code here // The following lines work (I can addSection()). _adapter = new ArrayAdapter(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) 

Agregó esta línea:

 setListAdapter(_sla); 

debajo de la línea:

 _sla.addSection("Results", _resultsAdapter); 

Puede usar MergeAdapter para su ListView. Esta es mi versión modificada y completamente probada.

 /** * 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 pieces = new ArrayList(); 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 sections = new ArrayList(); 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(); } } } 

También necesitará ListTitleAdapter para poner algunos títulos antes de cada adaptador si lo desea.

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

Y aquí hay un pequeño ejemplo sobre cómo usar estas dos clases.

 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); 
    Intereting Posts