0

我创建了自己的适配器,它扩展了 BaseAdapter 实现了可过滤。

在 getView 方法中,我偶尔会遇到索引越界错误:

    private ArrayList<ResultHolderData> originalData;
private ArrayList<ResultHolderData> arrayList;
private LayoutInflater inflater;
private ArrayList<ResultHolderData> suggestions;


public static class ResultHolderData {
    public String symbol;
    public String fullName;
    public ResultHolderData(String a, String b) {
        symbol=a;
        fullName=b;
    }
}

public static class ResultHolder {
    public TextView symName;
    public TextView symNameFull;
}
    @Override
public View getView(int position, View convertView, ViewGroup parent) {
    ResultHolder rh;

    if(convertView==null) {
        rh=new ResultHolder();
        convertView=inflater.inflate(R.layout.two_line_dropdown_item, null);
        rh.symName=(TextView) convertView.findViewById(R.id.autocompleteSym);
        rh.symNameFull=(TextView) convertView.findViewById(R.id.autocompleteName);
        convertView.setTag(rh);
    } else {
        rh=(ResultHolder) convertView.getTag();
    }

    //rh.symName.setTextColor(Color.GREEN);

     /***THE BELLOW LINE THROWS THE ERROR***/
    rh.symName.setText(arrayList.get(position).symbol);
    rh.symNameFull.setText(arrayList.get(position).fullName);
    //rh.symName.setText(arrayList.get(position));

    return convertView;
}

arrayList 表示过滤后的结果集:

            @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint,FilterResults results) {
       if(results.count>0 && results!=null) {
           arrayList=(ArrayList<ResultHolderData>) results.values;
           notifyDataSetChanged();
       } else {
           notifyDataSetInvalidated();
       }

    }

有时会发生错误,当您在下拉建议中有 2 个项目时,当键入另一个字母时,会导致下拉仅建议一个项目。然后它说:索引 1 无效,大小为 1。


我的意见:它通常发生在我快速输入时,所以我假设 NotifyDataSetChanged 正在进行中,但是 publishResults 更改了 arrayList 的内容,这会导致错误。但话又说回来,我希望这会在更多情况下发生?

还会弹出另一个错误:适配器的内容已更改,但 ListView 未收到通知。确保适配器的内容不是从后台线程修改的,而只是从 UI 线程修改的。

有什么想法吗?

4

1 回答 1

1

问题是publishResults中的这一行:

    arrayList=(ArrayList<ResultHolderData>) results.values;

它只是将arrayList指向这些结果,而不是我做了一个“浅拷贝”并清除了它之前的列表:

      arrayList.clear();
      for(ResultHolderData tempRhd : (ArrayList<ResultHolderData>)results.values)
               arrayList.add(tempRhd);

问题解决了!

于 2013-09-21T14:34:27.653 回答