我写了一个像这样的自己的ArrayAdapter:
public class PoiListAdapter extends ArrayAdapter<Poi> implements Filterable {
private Context context;
private final List<Poi> valuesPoi;
private ItemsFilter mFilter;
public PoiListAdapter(Context context, List<Poi> valuesPoi) {
super(context, R.layout.poilist);
this.context = context;
this.valuesPoi = valuesPoi;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.poilist, parent, false);
TextView textViewName = (TextView) rowView.findViewById(R.id.name_poi);
TextView textViewDis = (TextView) rowView
.findViewById(R.id.discrip_poi);
textViewName.setText(valuesPoi.get(position).getName());
textViewDis.setText(valuesPoi.get(position).getDiscription());
return rowView;
}
/**
* Implementing the Filterable interface.
*/
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemsFilter(this);
}
return mFilter;
}
public List<Poi> getValuesPoi() {
return valuesPoi;
}
public void addValuesPoi(Poi p) {
valuesPoi.add(p);
}
@Override
public void clear() {
valuesPoi.clear();
}
}
对于这个适配器,我想实现一个搜索功能。因此,我实现了一个自定义的Filter-Class:
public class ItemsFilter extends Filter {
private PoiListAdapter poiListAdapter;
public ItemsFilter(PoiListAdapter poiListAdapter) {
this.poiListAdapter = poiListAdapter;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
ArrayList<Poi> filterList = new ArrayList<Poi>();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<Poi> orginalList = new ArrayList<Poi>(
poiListAdapter.getValuesPoi());
for (Poi p : orginalList) {
if (p.getName().toLowerCase().contains(constraint))
filterList.add(p);
}
Log.i("DEBUG", orginalList.toString());
result.values = filterList;
result.count = filterList.size();
} else {
result.values = poiListAdapter.getValuesPoi();
result.count = poiListAdapter.getValuesPoi().size();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<Poi> fitems = (ArrayList<Poi>) results.values;
poiListAdapter.clear();
for (Poi p : fitems) {
poiListAdapter.addValuesPoi(p);
poiListAdapter.notifyDataSetChanged();
}
}
1.问题
....我得到了一个java.util.concurrentmodificationexception:
for (Poi p : fitems) {
poiListAdapter.addValuesPoi(p);
poiListAdapter.notifyDataSetChanged();
}
我认为问题在于我想在访问时修改Arraylist。我想我必须使用synchronized,但我以前从未使用它。
更新 这个问题解决了!代码:
for(Iterator<Poi> i = fitems.iterator(); i.hasNext();) {
Poi p = i.next();
poiListAdapter.addValuesPoi(p);
//poiListAdapter.notifyDataSetChanged();
}
2.问题
列表视图在开始时为空。一开始我想展示所有元素!搜索元素也没有显示任何内容! Listview目前没有显示任何内容!
答案 0 :(得分:2)
可以通过两种方式避免ConcurentModification:
poiListAdapter.addValuesPoi(p)在同步方法中添加此代码。无法同时访问同步方法。
使用Collections.synchronizedList
答案 1 :(得分:1)
for-each循环在内部使用Iterator,并且在迭代时不能向集合中添加任何内容(这就是异常的原因)。尝试创建ArrayList的新实例并进行交互
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<Poi> fitems = new ArrayList((ArrayList<Poi>) results.values);
poiListAdapter.clear();
for (Poi p : fitems) {
poiListAdapter.addValuesPoi(p);
poiListAdapter.notifyDataSetChanged();
}
}
for-each就像:
for(Iterator<Poi> i = fitms.iterator(); i.hasNext(); ) {
Poi item = i.next();
}
问题2:
列表在开始时为空,可能是因为您提交的数据集为空
答案 2 :(得分:1)
@JavaNullPointer:我遇到了和你一样的问题。我试图实现这里提供的解决方案,但是遇到了不同类型的问题。经过一段时间的思考,我假设默认的Filter可能正在使用对象的toString()方法进行过滤......这转向了我。这给我带来了很多麻烦......
阅读你的代码,我相信你想通过Poi类的名字字段过滤。如果是这样,那么快速的解决方案就是 解决方案:
public class Poi{
//your constructors and methods
@Override
public String toString(){
return getName();
}
答案 3 :(得分:0)
我可以解决我的问题。在这里我的解决方案!
package hsos.ds.helper;
import hsos.ds.db.Poi;
import java.util.ArrayList;
import java.util.List;
import android.widget.Filter;
public class ItemsFilter extends Filter {
private PoiListAdapter poiAdapter;
private List<Poi> valuesPoi;
private List<Poi> filteredPoi;
public ItemsFilter(PoiListAdapter _poiAdapter) {
this.poiAdapter = _poiAdapter;
this.valuesPoi = poiAdapter.getValuesPoi();
this.filteredPoi = poiAdapter.getFilteredPoi();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
constraint = constraint.toString().toLowerCase();
if (constraint == null || constraint.length() == 0) {
ArrayList<Poi> list = new ArrayList<Poi>(valuesPoi);
result.values = valuesPoi;
result.count = valuesPoi.size();
} else {
final ArrayList<Poi> orginalList = new ArrayList<Poi>(valuesPoi);
final ArrayList<Poi> filterList = new ArrayList<Poi>();
int count = orginalList.size();
for (int i = 0; i < count; i++) {
final Poi p = orginalList.get(i);
if (p.getName().toLowerCase().contains(constraint))
filterList.add(p);
}
result.values = filterList;
result.count = filterList.size();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredPoi = (List<Poi>) results.values;
poiAdapter.notifyDataSetChanged();
poiAdapter.clear();
int count = filteredPoi.size();
for (int i = 0; i < count; i++) {
poiAdapter.add(filteredPoi.get(i));
poiAdapter.notifyDataSetInvalidated();
}
}
}
和适配器:
public class PoiListAdapter extends ArrayAdapter实现了Filterable {
private List<Poi> valuesPoi;
private List<Poi> filteredPoi;
private ItemsFilter mFilter;
public PoiListAdapter(Context context, List<Poi> valuesPoi) {
super(context, R.layout.poilist);
this.valuesPoi = new ArrayList<Poi>(valuesPoi);
this.filteredPoi = new ArrayList<Poi>(valuesPoi);
this.mFilter = new ItemsFilter(this);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.poilist, null);
}
Poi p = filteredPoi.get(position);
if (p != null) {
TextView tt = (TextView) v.findViewById(R.id.name_poi);
TextView bt = (TextView) v.findViewById(R.id.discrip_poi);
if (tt != null) {
tt.setText(p.getName());
}
if (bt != null) {
bt.setText(p.getDiscription());
}
}
return v;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemsFilter(this);
}
return mFilter;
}
public List<Poi> getValuesPoi() {
return valuesPoi;
}
public List<Poi> getFilteredPoi() {
return filteredPoi;
}
}
要显示完整列表onStart()
,我在onStart()
- 我的活动方法中插入一点“黑客”,因为输入后会显示完整列表:
if(searchText!=null){
searchText.setText(" ");
searchText.setText("");
}