0

リストビューにカスタム アダプターを使用していますが、リストから特定のアイテムを検索するためのフィルターを適用したいのですが、その方法を教えてください。ArrayAdapter を拡張するアダプターに対してそれを行う方法はわかっていますが、私の場合は simplesectionadapter です。項目を検索したい edittext に入力されたテキストから、リストビューの上に 1 つの editText があります。

Collections.sort(contents, new Comparator<CategoryPojo>() {
            @Override
            public int compare(CategoryPojo s1, CategoryPojo s2) {
                return s1.getCategoryName().compareToIgnoreCase(
                        s2.getCategoryName());
            }
        });

        final CategoryAdapter adapter = new CategoryAdapter(this,
                android.R.layout.simple_list_item_1, contents);

        Sectionizer<CategoryPojo> alphabetSectionizer = new Sectionizer<CategoryPojo>() {

            @Override
            public String getSectionTitleForItem(CategoryPojo instance) {
                return instance.getCategoryName().substring(0, 1);
            }
        };

        final SimpleSectionAdapter<CategoryPojo> sectionAdapter = new SimpleSectionAdapter<CategoryPojo>(
                this, adapter, R.layout.section_header, R.id.title,
                alphabetSectionizer);

        listView.setFastScrollEnabled(true);
        listView.setTextFilterEnabled(true);
        listView.setAdapter(sectionAdapter);

これはsimplesectionadapterです

public class SimpleSectionAdapter<T> extends BaseAdapter implements Filterable{
    static final boolean DEBUG = false;
    static final String TAG = SimpleSectionAdapter.class.getSimpleName();

    // Constants
    private static final int VIEW_TYPE_SECTION_HEADER = 0;

    // Attributes
    private Context mContext;
    private BaseAdapter mListAdapter;
    private int mSectionHeaderLayoutId;
    private int mSectionTitleTextViewId;
    private Sectionizer<T> mSectionizer;
    private LinkedHashMap<String, Integer> mSections;
    AlphabetIndexer alphaIndexer;
    private Filter filter;



    /**
     * Constructs a {@linkplain SimpleSectionAdapter}.
     * 
     * @param context The context for this adapter.
     * @param listAdapter A {@link ListAdapter} that has to be sectioned.
     * @param sectionHeaderLayoutId Layout Id of the layout that is to be used for the header. 
     * @param sectionTitleTextViewId Id of a TextView present in the section header layout.
     * @param sectionizer Sectionizer for sectioning the {@link ListView}.
     */
    public SimpleSectionAdapter(Context context, BaseAdapter listAdapter, 
            int sectionHeaderLayoutId, int sectionTitleTextViewId, 
            Sectionizer<T> sectionizer) {

        if(context == null) { 
            throw new IllegalArgumentException("context cannot be null.");
        } else if(listAdapter == null) {
            throw new IllegalArgumentException("listAdapter cannot be null.");
        } else if(sectionizer == null) {
            throw new IllegalArgumentException("sectionizer cannot be null.");
        } else if(!isTextView(context, sectionHeaderLayoutId, sectionTitleTextViewId)) {
            throw new IllegalArgumentException("sectionTitleTextViewId should be a TextView.");
        }

        this.mContext = context;
        this.mListAdapter = listAdapter;
        this.mSectionHeaderLayoutId = sectionHeaderLayoutId;
        this.mSectionTitleTextViewId = sectionTitleTextViewId;
        this.mSectionizer = sectionizer;
        this.mSections = new LinkedHashMap<String, Integer>();

        // Find sections
        findSections();
    }

    private boolean isTextView(Context context, int layoutId, int textViewId) {
        View inflatedView = View.inflate(context, layoutId, null);
        View foundView = inflatedView.findViewById(textViewId);

        return foundView instanceof TextView;
    }

    @Override
    public int getCount() {
        return mListAdapter.getCount() + getSectionCount();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        SectionHolder sectionHolder = null;

        switch (getItemViewType(position)) {
        case VIEW_TYPE_SECTION_HEADER:
            if(view == null) {
                view = View.inflate(mContext, mSectionHeaderLayoutId, null);

                sectionHolder = new SectionHolder();
                sectionHolder.titleTextView = (TextView) view.findViewById(mSectionTitleTextViewId);

                view.setTag(sectionHolder);
            } else {
                sectionHolder = (SectionHolder) view.getTag();
            }
            break;

        default:
            view = mListAdapter.getView(getIndexForPosition(position), 
                    convertView, parent);
            break;
        }

        if(sectionHolder != null) {
            String sectionName = sectionTitleForPosition(position);
            sectionHolder.titleTextView.setText(sectionName);
        }

        return view;
    }

    @Override
    public boolean areAllItemsEnabled() {
        return mListAdapter.areAllItemsEnabled() ? 
                mSections.size() == 0 : false;
    }

    @Override
    public int getItemViewType(int position) {
        int positionInCustomAdapter = getIndexForPosition(position);
        return mSections.values().contains(position) ? 
                VIEW_TYPE_SECTION_HEADER : 
                    mListAdapter.getItemViewType(positionInCustomAdapter) + 1;
    }

    @Override
    public int getViewTypeCount() {
        return mListAdapter.getViewTypeCount() + 1;
    }

    @Override
    public boolean isEnabled(int position) {
        return mSections.values().contains(position) ? 
                false : mListAdapter.isEnabled(getIndexForPosition(position));
    }

    @Override
    public Object getItem(int position) {
        return mListAdapter.getItem(getIndexForPosition(position));
    }

    @Override
    public long getItemId(int position) {
        return mListAdapter.getItemId(getIndexForPosition(position));
    }

    @Override
    public void notifyDataSetChanged() {
        mListAdapter.notifyDataSetChanged();
        findSections();
        super.notifyDataSetChanged();
    }

    /**
     * Returns the actual index of the object in the data source linked to the this list item.
     * 
     * @param position List item position in the {@link ListView}.
     * @return Index of the item in the wrapped list adapter's data source.
     */
     public int getIndexForPosition(int position) {
         int nSections = 0;

         Set<Entry<String, Integer>> entrySet = mSections.entrySet();
         for(Entry<String, Integer> entry : entrySet) {
             if(entry.getValue() < position) {
                 nSections++;
             }
         }

         return position - nSections;
     }

     static class SectionHolder {
         public TextView titleTextView;
     }

     private void findSections() {
         int n = mListAdapter.getCount();
         int nSections = 0;
         mSections.clear();

         for(int i=0; i<n; i++) {
             String sectionName = mSectionizer.getSectionTitleForItem((T) mListAdapter.getItem(i));


             if(!mSections.containsKey(sectionName)) {
                 mSections.put(sectionName, i + nSections);
                 nSections ++;
             }
         }

         if(DEBUG) {
             Log.d(TAG, String.format("Found %d sections.", mSections.size()));
         }
     }

     private int getSectionCount() {
         return mSections.size();
     }

     private String sectionTitleForPosition(int position) {
         String title = null;

         Set<Entry<String, Integer>> entrySet = mSections.entrySet();
         for(Entry<String, Integer> entry : entrySet) {
             if(entry.getValue() == position) {
                 title = entry.getKey();
                 break;
             }
         }

         return title;
     }
4

1 に答える 1

1

addTextChangedListenerメソッドで & を使用しonTextChangedて、検索文字列を取得し、この文字列を listItems と一致させ、検索項目の新しいリストを準備します。次に、アダプターを再初期化して に設定しListViewます。

于 2013-02-08T06:08:41.920 に答える