在我的应用程序中,我创建了一个自定义列表视图,我想实现一个过滤器,以便可以根据EditText中输入的文本过滤列表。我使用BaseAdapter作为一个单独的类,我在我的主要活动中调用该类。我还在我的main活动中实现了addTextChangedListener(),我还在BaseAdapter类中实现了getFilter()。但我不知道如何使用getFilter()并可以相应地过滤我的列表。在列表中,我将添加JSON URL中的值。请帮助我告诉我如何使用getFilter()来过滤我的列表。
Activity类的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView)findViewById(R.id.listView1);
et1 = (EditText)findViewById(R.id.editText1);
inflator = getLayoutInflater();
et1.addTextChangedListener(this);
JsonParser jParser = new JsonParser();
JSONObject json = jParser.getJSONfromUrl(url);
try
{
JSONArray explore = json.getJSONArray("explore");
for(int i=0; i<explore.length(); i++)
{
JSONObject exp = explore.getJSONObject(i);
list.add(exp.getString("username"));
}
}
catch(JSONException e)
{
e.printStackTrace();
}
srchadptr = new SearchAdapter(this, inflator, list);
lv.setAdapter(srchadptr);
}
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
srchadptr.getFilter().filter(s);
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
BaseAdapter类的代码:
public class SearchAdapter extends BaseAdapter implements Filterable {
Context context;
LayoutInflater inflater;
Button btn;
View vw;
ArrayList<String> list = new ArrayList<String>();
public SearchAdapter(Context context, LayoutInflater inflater, ArrayList<String> list) {
// TODO Auto-generated constructor stub
this.context = context;
this.inflater = inflater;
this.list = list;
}
/*public CharSequence filter(CharSequence cs) {
return cs;
}*/
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LinearLayout ll = (LinearLayout) vw;
final EditText edt = ((EditText)ll.getChildAt(0));
vw = inflater.inflate(R.layout.list_items, null);
ImageView img = (ImageView)vw.findViewById(R.id.imageView1);
TextView tv = (TextView)vw.findViewById(R.id.textView1);
btn = (Button)vw.findViewById(R.id.button1);
tv.setText(String.valueOf(list.get(position)));
btn.setText(String.valueOf(list.get(position)));
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, list.get(position), Toast.LENGTH_LONG).show();
}
});
return vw;
}
public android.widget.Filter getFilter() {
// TODO Auto-generated method stub
return new android.widget.Filter() {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
return null;
}
};
}
}
提前致谢...
答案 0 :(得分:9)
我希望此示例可以帮助您
Main_Activity中的
EditText etSearch;
BaseAdapterFilterable adapter;
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Listview name of the class
Listview.this.adapter.getFilter().filter(s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
适配器中的将此类用于getfilter方法
public class filter_here extends Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
FilterResults Result = new FilterResults();
// if constraint is empty return the original names
if(constraint.length() == 0 ){
Result.values = Original_Names;
Result.count = Original_Names.size();
return Result;
}
ArrayList<String> Filtered_Names = new ArrayList<String>();
String filterString = constraint.toString().toLowerCase();
String filterableString;
for(int i = 0; i<Original_Names.size(); i++){
filterableString = Original_Names.get(i);
if(filterableString.toLowerCase().contains(filterString)){
Filtered_Names.add(filterableString);
}
}
Result.values = Filtered_Names;
Result.count = Filtered_Names.size();
return Result;
}
@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
// TODO Auto-generated method stub
Names = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
也在您的适配器中从 filter_here 类
返回实例@Override
public Filter getFilter() {
// TODO Auto-generated method stub
return filter;
}
答案 1 :(得分:2)
在BaseAdapter中,存储列表的两个副本,一个原件和一个已过滤。并更改BaseAdapter中的所有引用,仅使用已过滤的列表。
1)在您的活动中,激活 ListView 上的过滤器: lv.setTextFilterEnabled(真);
2)在textWatcher中,触发listadapter上的过滤器 srchadptr.getFilter()。(多个)滤波器
3)更新baseadapter以存储两个数据副本,并更改引用以引用过滤列表而不是原始列表。
public class SearchAdapter extends BaseAdapter implements Filterable {
List<String> list = new ArrayList<String>();
List<String> listFiltered = new ArrayList<String>();
public SearchAdapter(Context context, ArrayList<String> list) {
this.context = context;
this.inflater = LayoutInflater.from(context)
this.list = list;
this.listFiltered=list;
}
public int getCount() {
return listFiltered.size();//note the change
}
public Object getItem(int position) {
return listFiltered.get(position);//note the change
}
//only altered lines shown in this function (change ``list`` to ``listFiltered``)
public View getView(final int position, View convertView, ViewGroup parent) {
tv.setText(String.valueOf(listFiltered.get(position)));
btn.setText(String.valueOf(listFiltered.get(position)));
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(context, listFiltered.get(position), Toast.LENGTH_LONG).show();
}
});
}
//now write your filter function
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//no constraint given, just return all the data. (no search)
results.count = list.size();
results.values = list;
} else {//do the search
List<String> resultsData = new ArrayList<>();
String searchStr = constraint.toString().toUpperCase();
for (String s : list)
if (s.toUpperCase().contains(searchStr)) resultsData.add(s);
results.count = resultsData.size();
results.values = resultsData;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
listFiltered = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
};
}
答案 2 :(得分:0)
我觉得使用过滤器不是那么方便..我是怎么做的:
((EditText)findViewById(R.id.etSearch)).addTextChangedListener(new TextWatcher(){
private boolean mCountIncreased;
@Override
public void afterTextChanged(Editable s) {
if (s.toString().length() == 0){
mDisplayedList.clear();
mDisplayedList.addAll(mFullList);
mListAdapter.notifyDataSetChanged();
return;
}
if (mCountIncreased){
mDisplayedList.clear();
mDisplayedList.addAll(mFullList);
}
List<Item> toRemove = new ArrayList<Item>();
for (Item item : mDisplayedList){
if (someCondition)
toRemove.add(currency);
}
}
mDisplayedList.removeAll(toRemove);
mListAdapter.notifyDataSetChanged();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
mCountIncreased = after <= count;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
请注意,您必须更改适配器以使用mDisplayedList而不是mFullList ..就是这样。
当你的列表中包含大量条目时,这可能会产生一些开销..但我的工作方式是+ -300项目,我没有注意到任何内容。
希望它有所帮助, 维拉德