Android 为自定义Listview向自定义SimpleAdapter添加搜索
我有一个ListView工作非常好。现在我想在listItem行的某个textview上添加搜索功能 例如,我在工具栏中有一个editText或Searchview。 我的ListView有一个项目,即状态字段。现在我只想从listview中搜索状态 我在互联网上找到了很多解决方案,但我有自己定制的简单适配器类,我不知道如何在其中添加搜索 以下是我的扩展SimpleAdapter代码:Android 为自定义Listview向自定义SimpleAdapter添加搜索,android,listview,baseadapter,simpleadapter,Android,Listview,Baseadapter,Simpleadapter,我有一个ListView工作非常好。现在我想在listItem行的某个textview上添加搜索功能 例如,我在工具栏中有一个editText或Searchview。 我的ListView有一个项目,即状态字段。现在我只想从listview中搜索状态 我在互联网上找到了很多解决方案,但我有自己定制的简单适配器类,我不知道如何在其中添加搜索 以下是我的扩展SimpleAdapter代码: public class ExtendedSimpleAdapter extends SimpleAdapte
public class ExtendedSimpleAdapter extends SimpleAdapter implements Filterable {
List<? extends Map<String, ?>> map; // if fails to compile, replace with List<HashMap<String, Object>> map
String[] from;
int layout;
int[] to;
private ArrayList<Map<String, ?>> mUnfilteredData;
//private ArrayList<Product> mDisplayedValues;
Context context;
private Filter mFilter;
LayoutInflater mInflater;
public ExtendedSimpleAdapter(Context context, List<? extends Map<String, ?>> data, // if fails to compile, do the same replacement as above on this line
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
layout = resource;
map = data;
this.from = from;
this.to = to;
this.context = context;
}
@Override
public int getCount() {
return map.size();
}
@Override
public Object getItem(int position) {
return map.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return this.createViewFromResource(position, convertView, parent, layout);
}
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);
} else {
v = convertView;
}
this.bindView(position, v);
return v;
}
private void bindView(int position, View view) {
final Map dataSet = map.get(position);
if (dataSet == null) {
return;
}
final ViewBinder binder = super.getViewBinder();
final int count = to.length;
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
final Object data = dataSet.get(from[i]);
String text = data == null ? "" : data.toString();
if (text == null) {
text = "";
}
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data == null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else if (data instanceof Bitmap) {
setViewImage((ImageView) v, (Bitmap) data);
} else {
setViewImage((ImageView) v, text);
}
} else if (v instanceof RatingBar) {
float score = Float.parseFloat(data.toString()); //2
((RatingBar) v).setRating(score);
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
}
}
}
private void setViewImage(ImageView v, Bitmap bmp) {
v.setImageBitmap(bmp);
}
public Filter getFilter() {
if (mFilter == null) {
mFilter = new SimpleFilter();
}
return mFilter;
}
private class SimpleFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mUnfilteredData == null) {
mUnfilteredData = new ArrayList<Map<String, ?>>(map);
}
if (prefix == null || prefix.length() == 0) {
ArrayList<Map<String, ?>> list = mUnfilteredData;
results.values = list;
results.count = list.size();
} else {
String prefixString = prefix.toString().toLowerCase();
ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;
int count = unfilteredValues.size();
ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count);
for (int i = 0; i < count; i++) {
Map<String, ?> h = unfilteredValues.get(i);
if (h != null) {
int len = to.length;
for (int j = 0; j < len; j++) {
String str = (String) h.get(from[j]);
String[] words = str.split(" ");
int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
String word = words[k];
if (word.toLowerCase().startsWith(prefixString)) {
newValues.add(h);
break;
}
}
}
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
//noinspection unchecked
map = (List<Map<String, ?>>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
如您所见,我在simpleadapter中有一个标记状态,如何对其执行搜索
编辑
现在,当我从searview栏中搜索某些内容时,我遇到了这个错误
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at com.adnan.zwd.hidoctor.Chat.ExtendedSimpleAdapter.getCount(ExtendedSimpleAdapter.java:52)
at android.widget.AdapterView.checkFocus(AdapterView.java:739)
at android.widget.AdapterView$AdapterDataSetObserver.onInvalidated(AdapterView.java:862)
at android.widget.AbsListView$AdapterDataSetObserver.onInvalidated(AbsListView.java:6211)
at android.database.DataSetObservable.notifyInvalidated(DataSetObservable.java:50)
at android.widget.BaseAdapter.notifyDataSetInvalidated(BaseAdapter.java:59)
at com.adnan.zwd.hidoctor.Chat.ExtendedSimpleAdapter$SimpleFilter.publishResults(ExtendedSimpleAdapter.java:222)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
您可以在cicle中使用if(from[i].contains(constraints)),将结果保存在字符串[]中,最后将该数组分配给适配器,以便它使用它。但是,我建议您更改为RecicleView而不是ListView
这个例子。。。没有测试它,但应该可以工作,或者至少可以帮助您。。我希望如此。有趣的事实。。。我也从你的代码中学到了一些东西。谢谢你给我这个机会
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
from = (String[]) results.values; // change dateset
notifyDataSetChanged();
// notifies the data with new filtered values
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new Filter.FilterResults(); // Holds the results of a filtering operation in values
// ArrayList<Product> FilteredArrList = new ArrayList<Product>();
String [] filtered = new String[from.length];
int index=0;
for(int i=0;i<from.length;i++)
if(from[i].contains(constraint))
{
filtered[index++]=from[i];
}
results.values = filtered;
results.count=index;
return results;
}
};
return filter;
}
@覆盖
公共过滤器getFilter(){
过滤器过滤器=新过滤器(){
@抑制警告(“未选中”)
@凌驾
受保护的void publishResults(CharSequence约束、FilterResults结果){
from=(字符串[])results.values;//更改日期集
notifyDataSetChanged();
//用新的筛选值通知数据
}
@凌驾
受保护的筛选器结果性能筛选(CharSequence约束){
FilterResults results=new Filter.FilterResults();//以值的形式保存筛选操作的结果
//ArrayList FilteredArrList=新的ArrayList();
String[]filtered=新字符串[from.length];
int指数=0;
对于(int i=0;你能提供任何例子吗?我对自定义适配器不熟悉。即使我发现recyclerView真的很难使用,也请建议如何使用它。谢谢,这是因为我更新了数据源,但没有更新列表>映射;
对象,很抱歉,我的错,你可以用它来获取数据集中的对象数量,在事实上,可能只需更新“映射”就可以让它工作。因此,在publishResults()中,将映射代码放在只包含过滤结果的位置。
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
from = (String[]) results.values; // change dateset
notifyDataSetChanged();
// notifies the data with new filtered values
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new Filter.FilterResults(); // Holds the results of a filtering operation in values
// ArrayList<Product> FilteredArrList = new ArrayList<Product>();
String [] filtered = new String[from.length];
int index=0;
for(int i=0;i<from.length;i++)
if(from[i].contains(constraint))
{
filtered[index++]=from[i];
}
results.values = filtered;
results.count=index;
return results;
}
};
return filter;
}