Pertanyaan Android melampirkan beberapa adaptor ke satu adaptor


Saya telah menggunakan SeparatedListAdapter yang sangat terkenal dan berfungsi sempurna, tetapi tampaknya saya tidak dapat menggunakan addSection () untuk menambahkan SimpleAdapter, karena aplikasi dihentikan. Saya menyediakan beberapa kode untuk menunjukkan apa yang saya coba lakukan dan mendapatkan beberapa panduan untuk menyelesaikan masalah ini. Tolong beri tahu saya jika Anda memerlukan kode lain atau apa pun:

// 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)

4
2017-11-01 08:54


asal


Jawaban:


Menambahkan baris ini:

setListAdapter(_sla);

dibawah garis:

_sla.addSection("Results", _resultsAdapter);

3
2017-11-01 09:15



Anda dapat menggunakan MergeAdapter untuk ListView Anda. Ini adalah versi saya yang telah dimodifikasi dan teruji sepenuhnya.

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

Anda juga akan membutuhkan ListTitleAdapter untuk menaruh beberapa judul sebelum setiap adaptor jika Anda mau.

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

Dan di sini adalah contoh kecil tentang cara menggunakan dua kelas ini.

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

17
2018-03-16 09:08