【发布时间】:2018-10-09 04:36:25
【问题描述】:
我有一个自定义ListView。除非尝试过滤用户搜索,否则它工作正常。
显示ListView的代码:
private void listShow() {
warranties=db.getAllServWarr();
adapter=new WarrantyAdapter(serviceswarranty_activity.this,warranties);
listView.setAdapter(adapter);
}
在自定义适配器中实现过滤器的代码:
public class WarrantyAdapter extends ArrayAdapter implements Filterable{
private ArrayList<ServicesWarranty> warrantyList;
private ArrayList<ServicesWarranty> filteredList;
private ItemFilter mFilter = new ItemFilter();
private Context context;
private int currPosition;
public WarrantyAdapter(@NonNull Context context,ArrayList<ServicesWarranty> warrantyList) {
super(context, R.layout.serviceswarranty_item,warrantyList);
this.warrantyList=warrantyList;
this.filteredList=warrantyList;
this.context=context;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ServicesWarranty sw=warrantyList.get(position);
currPosition=position;
WarrantyAdapter.ViewHolder holder;
if(convertView==null){
LayoutInflater inflater=(LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView=inflater.inflate(R.layout.serviceswarranty_item,parent,false);
holder=new WarrantyAdapter.ViewHolder();
holder.lockno=(TextView)convertView.findViewById(R.id.lockNum_warrantyitem);
holder.fromdate=(TextView)convertView.findViewById(R.id.fromDate_warrantyItem);
holder.todate=(TextView)convertView.findViewById(R.id.toDate_warrantyItem);
holder.editIc=(ImageView)convertView.findViewById(R.id.editic_warrantyItem);
holder.deleteIc=(ImageView)convertView.findViewById(R.id.deleteic_warrantyItem);
convertView.setTag(holder);
}else{
holder=(WarrantyAdapter.ViewHolder) convertView.getTag();
}
holder.fill(sw);
return convertView;
}
private class ViewHolder{
public TextView lockno;
public TextView fromdate;
public TextView todate;
public ImageView editIc;
public ImageView deleteIc;
public void fill(final ServicesWarranty sw){
lockno.setText(String.valueOf(sw.getLockNumber()));
fromdate.setText(sw.getBeginDate());
todate.setText(sw.getEndDate());
editIc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(context,Add2warranty.class);
intent.putExtra("AddedWarrantyLockNo",sw.getLockNumber().toString());
context.startActivity(intent);
}
});
deleteIc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder deleteAlert=new AlertDialog.Builder(context);
deleteAlert.setMessage("آیا از حذف گارانتی با شماره قفل "+sw.getLockNumber().toString()+" اطمینان دارید؟")
.setPositiveButton("بله", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
AppDBHelper db=new AppDBHelper(context);
boolean res=db.deleteFromWarranty(sw.getID());
if(res) {
Toast.makeText(context, "Delete successfully", Toast.LENGTH_SHORT).show();
warrantyList.remove(currPosition);
notifyDataSetChanged();
}
}
})
.setNegativeButton("خیر",null)
.show();
}
});
}
}
public Filter getFilter() {
return mFilter;
}
private class ItemFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString();
FilterResults results = new FilterResults();
final List<ServicesWarranty> list = filteredList;
int count = list.size();
final ArrayList<ServicesWarranty> nlist = new ArrayList<ServicesWarranty>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
filterableString = list.get(i).getLockNumber().toString();
if (filterableString.toLowerCase().contains(filterString)) {
nlist.add(list.get(i));
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
warrantyList = (ArrayList<ServicesWarranty>) results.values;
notifyDataSetChanged();
}
}
}
我还将它添加到我的活动中以启用过滤器搜索
inputSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
if(s.length()>0)
adapter.getFilter().filter(s);
return false;
}
});
当我调试这个程序时,adapter.getFilter().filter(s); 工作正常,但在接近函数结束时程序强制关闭。
这是我的 logcat 信息
FATAL EXCEPTION: main
Process: com.example.zahra.prj1, PID: 18592
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
在我的ListView 中,我有 2 个项目,其值为 13 和 14。我在搜索文本框中输入 4,因此列表大小应该是 1。
为什么过滤不起作用?感谢您的帮助。
【问题讨论】:
-
使用 LogCat 检查与您的崩溃相关的 Java 堆栈跟踪:stackoverflow.com/questions/23353173/…
-
谢谢你,我把 logcat 信息添加到我的帖子中
-
能否贴出getItemCount函数代码
-
另外我想问一下你为什么还在使用 ListView 而不是 RecyclerView
标签: android listview android-arrayadapter android-filterable