我正在尝试在基础适配器上实现getFilter()以过滤List上的搜索结果。有没有关于如何实现getFilter()的示例?
MainActivity.java
final AppInfoAdapter adapter = new AppInfoAdapter(this, Utilities.getSystemFilteredApplication(this), getPackageManager());
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s); //Filter from my adapter
adapter.notifyDataSetChanged(); //Update my view
}
AppInfoAdapter.java
package com.example.permission;
import java.util.List;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
public class AppInfoAdapter extends BaseAdapter implements Filterable{
private Context mContext;
private List mListAppInfo;
PackageManager mPackManager;
public AppInfoAdapter(Context c, List list, PackageManager pm) {
mContext = c;
mListAppInfo = list;
mPackManager = pm;
}
public int getCount() {
return mListAppInfo.size();
}
public Object getItem(int position) {
return mListAppInfo.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// get the selected entry
ApplicationInfo entry = (ApplicationInfo) mListAppInfo.get(position);
// reference to convertView
View v = convertView;
// inflate new layout if null
if(v == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
v = inflater.inflate(R.layout.layout_appinfo, null);
}
// load controls from layout resources
ImageView ivAppIcon = (ImageView)v.findViewById(R.id.ivIcon);
TextView tvAppName = (TextView)v.findViewById(R.id.tvName);
TextView tvPkgName = (TextView)v.findViewById(R.id.tvPack);
// set data to display
ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
tvAppName.setText(entry.loadLabel(mPackManager));
tvPkgName.setText(entry.packageName);
// return view
return v;
}
public Filter getFilter() {
// TODO Auto-generated method stub
return null;
}
}
编辑:编辑代码并添加完整的AppInfoAdapter.java
答案 0 :(得分:7)
将此类用于getfilter方法
//this is a simple class that filtering the ArrayList of strings used in adapter
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();
}
}
在getfilter中返回实例
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
return filter;
}
答案 1 :(得分:5)
在公共适配器类中定义List的ArrayList,它将包含原始列表的临时项目。
public class MyAdapter extends BaseAdapter implements Filterable{
public static ArrayList<String> temporarylist;
public static ArrayList<String> OriginalList;
private Activity activity;
public MyAdapter(Activity activity, ArrayList<String> OriginalList) {
super();
this.activity=activity;
this.OriginalList = OriginalList;
temporarylist=OriginalList;
}
.
.
.
使用以下代码[作为示例]创建getFilter()方法:
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
temporarylist=(ArrayList<String>)results.values;
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<String> FilteredList= new ArrayList<String>();
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
results.values = OriginalList;
results.count = OriginalList.size();
}
else {
for (int i = 0; i < OriginalList.size(); i++) {
String data = OriginalList.get(i);
if (data.toLowerCase().contains(constraint.toString())) {
FilteredList.add(data);
}
}
results.values = FilteredList;
results.count = FilteredList.size();
}
return results;
}
};
return filter;
}
最后在你的EditText活动中:
MyAdapter adapter;
ArrayList<String> items;
ListView list = (ListView) findViewById(R.id.list);
items = new ArrayList<String>();
for (int i=0;i<30;i++){
items.add("Hello world "+String.valueof(i));
}
adapter = new GameAdapter(this, items);
list.setAdapter(adapter);
EditText inputSearch = (EditText) findViewById(R.id.Search_txt);
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MyActivity.this.adapter.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
}
});
答案 2 :(得分:1)
您需要返回Filter
的实例。编写过滤器,子类Filter
并实现performFiltering
和publishResults
。请参阅docs。
答案 3 :(得分:1)
你可以发布完整的AppInfoAdapter
吗?也有任何理由延伸到BaseAdapter
而不是ArrayAdapter
?如果您有ArrayList
个对象,请使用ArrayAdapter
,它已经实现了Filterable
接口。
实际上您使用的是List
,您的适配器可以重写为ArrayAdapter
已扩展Filterable
。
public class AppInfoAdapter extends ArrayAdapter<ApplicationInfo> {
private Context mContext;
PackageManager mPackManager;
public AppInfoAdapter(Context c, List<ApplicationInfo> list, PackageManager pm) {
super(c, 0, new ArrayList<ApplicationInfo>());
mContext = c;
mPackManager = pm;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// get the selected entry
ApplicationInfo entry = (ApplicationInfo) getItem(position);
// reference to convertView
View v = convertView;
// inflate new layout if null
if(v == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
v = inflater.inflate(R.layout.layout_appinfo, null);
}
// load controls from layout resources
ImageView ivAppIcon = (ImageView)v.findViewById(R.id.ivIcon);
TextView tvAppName = (TextView)v.findViewById(R.id.tvName);
TextView tvPkgName = (TextView)v.findViewById(R.id.tvPack);
// set data to display
ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
tvAppName.setText(entry.loadLabel(mPackManager));
tvPkgName.setText(entry.packageName);
// return view
return v;
}
}
答案 4 :(得分:1)
一般程序
步骤1:
listview.setTextFilterEnabled(true);
第2步:
public class AppInfoAdapter extends BaseAdapter implements Filterable{
private List mListAppInfo;
private List mListAppInfoFiltered;
public AppInfoAdapter(Context c, List list, PackageManager pm) {
mContext = c;
mListAppInfo = list;
mPackManager = pm;
mPackManagerFiltered = pm; //added line
}
第3步:
public int getCount() {
return mListAppInfoFiltered.size();
}
public Object getItem(int position) {
return mListAppInfoFiltered.get(position);
}
public View getView(int position, View convertView, ViewGroup parent) {
// get the selected entry
ApplicationInfo entry = (ApplicationInfo) mListAppInfoFiltered.get(position);
}
第4步: 我不确定你的列表是什么类型,所以假设一个字符串列表:
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//no search, so just return all the data
results.count = mListAppInfo.size();
results.values = mListAppInfo;
} else {//do the search
List<String> resultsData = new ArrayList<>();
String searchStr = constraint.toString().toUpperCase();
for (String s : mListAppInfo)
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) {
mListAppInfoFiltered = (ArrayList<MyObject>) results.values;
notifyDataSetChanged();
}
};
}
}
答案 5 :(得分:0)
getFilter()可以在适配器中覆盖并返回包含已过滤列表的过滤器对象。 Filter()类有两个关键方法; 执行过滤和 publishResults 。第一种方法在工作线程中执行过滤,后一种方法返回过滤的对象列表。
您可以参考下面的示例代码
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
if (results.count == 0) {
notifyDataSetInvalidated();
}else{
mListAppInfo = (ArrayList<SampleItem>) results.values;
notifyDataSetChanged();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = mListAppInfo;
results.count = mListAppInfo.size();
}else{
ArrayList<SampleItem> filter_items = new ArrayList<>();
for (SampleItem item : mListAppInfo) {
if (item.getItemName().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
filter_items.add(item);
}
}
results.values = filter_items ;
results.count = filter_items.size();
}
return results;
}
};
}
希望你觉得它很有用。
答案 6 :(得分:-1)
使用ArrayAdapter扩展您的类,然后重写方法,并创建过滤器类的对象并随之返回。