将搜索过滤器应用于自定义列表

时间:2013-02-13 06:17:30

标签: android listview search adapter

我有一些来自数据库的数据,我在列表视图中显示之前,我正在使用索引器按字母顺序排列项目。所以我的列表显示按字母顺序排列的项目部分标题。现在我想从列表中搜索项目使用在editText中输入的单词。如何做到这一点我知道我们可以使用filter和textwatcher但是如何使用它,因为我设置为listview的适配器不是arrayadapter而是SimpleSectionAdapter。

dbHelper.openDataBase();
        Cursor cursor = dbHelper.fetchAllRecords();
        Log.v("count of records", cursor.getCount() + "");
        ArrayList<CategoryPojo> contents = new ArrayList<CategoryPojo>();
        cursor.moveToFirst();
        CategoryPojo cp;
        while (cursor.isAfterLast() == false) {
            cp = new CategoryPojo();
            cp.setCategoryName(cursor.getString(cursor
                    .getColumnIndex(DataBaseHelper.KEY_CATEGORIES)));
            cp.setCategoryImageName(cursor.getString(cursor
                    .getColumnIndex(DataBaseHelper.KEY_IMAGENAME)));
            cursor.moveToNext();
            contents.add(cp);
        }
        cursor.close();
        dbHelper.close();
        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);
        edtSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {


            }
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });

And Simplesectionadapter is 

公共类SimpleSectionAdapter扩展BaseAdapter实现Filterable {private ArrayList mOriginalValues,mDisplayedValues;

static final boolean DEBUG = false;
static final String TAG = SimpleSectionAdapter.class.getSimpleName();
// Constants
private static final int VIEW_TYPE_SECTION_HEADER = 0;


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


public SimpleSectionAdapter(Context context, ArrayList<CategoryPojo> contents, 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.mOriginalValues = contents;
    this.mDisplayedValues = contents; 
    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 mDisplayedValues.size();
    //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++) {
        @SuppressWarnings("unchecked")
        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;
}



@Override
public Filter getFilter() {

    return new android.widget.Filter() {

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            mDisplayedValues = (ArrayList<CategoryPojo>) results.values;

            // has
            // the
            // filtered
            // values

            notifyDataSetChanged(); // notifies the data with new filtered
            // values
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults(); // Holds the
            // results of a
            // filtering
            // operation in
            // values
            ArrayList<CategoryPojo> FilteredArrList = new ArrayList<CategoryPojo>();

            if (mOriginalValues == null) {

                mOriginalValues = new ArrayList<CategoryPojo>(mDisplayedValues); 

            }


            if (constraint == null || constraint.length() == 0) {

                // set the Original result to return
                results.count = mOriginalValues.size();
                results.values = mOriginalValues;
            } else {
                constraint = constraint.toString().toLowerCase();
                for (int i = 0; i < mOriginalValues.size(); i++) {
                    String data = String.valueOf(mOriginalValues.get(i)
                            .getCategoryName());
                    if (data.toLowerCase()
                            .startsWith(constraint.toString())) {
                        FilteredArrList.add(new CategoryPojo(
                                mOriginalValues.get(i).getCategoryName(),
                                mOriginalValues.get(i)
                                .getCategoryImageName()));
                    }
                }
                // set the Filtered result to return
                results.count = FilteredArrList.size();
                results.values = FilteredArrList;
            }
            return results;
        }
    };
}

}

3 个答案:

答案 0 :(得分:1)

Textwatcher代码

inputSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence cs,
                int arg1, int arg2, int arg3) {
            // When user changed the Text
            mainmenu2.this.adapter1.getFilter().filter(
                    cs);
        }

        @Override
        public void beforeTextChanged(CharSequence arg0,
                int arg1, int arg2, int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub
        }
    });

和里面

public class SimpleSectionAdapter<T> extends BaseAdapter {

像这样实现Filterable

public class SimpleSectionAdapter<T> extends BaseAdapter implements Filterable

然后在SimpleSectionAdapter中使用这个android.widget.Filter getFilter()(“根据你的编辑它,它只是一个例子)

public android.widget.Filter getFilter() {
        // TODO Auto-generated method stub
        return new android.widget.Filter() {

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                // TODO Auto-generated method stub
                 mDisplayedValues = (ArrayList<Product>) results.values; // has the filtered values
                notifyDataSetChanged();  // notifies the data with new filtered values
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                // TODO Auto-generated method stub
                  FilterResults results = new FilterResults();        // Holds the results of a filtering operation in values
                ArrayList<Product> FilteredArrList = new ArrayList<Product>();

                if (mOriginalValues == null) {
                    mOriginalValues = new ArrayList<Product>(mDisplayedValues); // saves the original data in mOriginalValues
                }

                /********
                 * 
                 *  If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
                 *  else does the Filtering and returns FilteredArrList(Filtered)  
                 *
                 ********/
                if (constraint == null || constraint.length() == 0) {

                    // set the Original result to return  
                    results.count = mOriginalValues.size();
                    results.values = mOriginalValues;
                } else {
                    constraint = constraint.toString().toLowerCase();
                    for (int i = 0; i < mOriginalValues.size(); i++) {
                        String data = String.valueOf(mOriginalValues.get(i).fname);
                        if (data.toLowerCase().startsWith(constraint.toString())) {
                            FilteredArrList.add(new Product(mOriginalValues.get(i).id,mOriginalValues.get(i).fname,mOriginalValues.get(i).lname));
                        }
                    }
                    // set the Filtered result to return
                    results.count = FilteredArrList.size();
                    results.values = FilteredArrList;
                }
                return results;
            }
        };
    }

答案 1 :(得分:0)

使用TextwatcherClick here more details

public class MainActivity extends Activity {

ArrayList<String> list = new ArrayList<String>();

private EditText searchEdt;



/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    // making it full screen
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_ugsimply_beta);
    list.add("Samsung Tab");
    list.add("Samsung Note");
    list.add("Nokia Lumia");
    list.add("Nokia 5130");
    list.add("Sony Xperia");
    searchEdt = (EditText) findViewById(R.id.searchEdt);


    searchEdt.addTextChangedListener(new TextWatcher() {

        private int textlength;
        private ArrayList<String> arrayList_sort = new ArrayList<String>();

        public void afterTextChanged(Editable s) {
            // Abstract Method of TextWatcher Interface.
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // Abstract Method of TextWatcher Interface.
        }

        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            textlength = searchEdt.getText().length();
            if (arrayList_sort != null)
                arrayList_sort.clear();

            for (int i = 0; i < list.size(); i++) {

                if (textlength <= list.get(i).toString().length()) {

                    if (searchEdt
                            .getText()
                            .toString()
                            .equalsIgnoreCase(
                                    (String) list.get(i).toString()
                                            .subSequence(0, textlength))) {
                        arrayList_sort.add(list.get(i));
                        Log.d("TAG", "log" + arrayList_sort.size());
                    }
                }
            }

        }
    });

}

}

答案 2 :(得分:0)

在onTextChanged上写这样......

@Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {


        if (s.toString().length() >= THRESHOLD ){
            FetchResult fetchResult = new FetchResult();
            fetchResult.execute(s.toString());


        }

    }