android attaching multiple adapters to one adapter

前端 未结 2 1433
孤独总比滥情好
孤独总比滥情好 2020-11-30 09:22

I have been using the SeparatedListAdapter which is very well known and works perfectly, but it seems that I cannot use the addSection() to add a SimpleAdapter, because the

相关标签:
2条回答
  • 2020-11-30 10:01

    Added this line:

    setListAdapter(_sla);
    

    below the line:

    _sla.addSection("Results", _resultsAdapter);
    
    0 讨论(0)
  • 2020-11-30 10:19

    You can use MergeAdapter for your ListView. This is my modified and fully tested version.

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

    You also will need ListTitleAdapter to put some titles before each adapter if you want.

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

    And here is small example on how to use these two classes.

    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);
    
    0 讨论(0)
提交回复
热议问题