由远程API填充的AutoCompleteTextView提供异常IndexOutOfBoundsException OnItemClickListener

时间:2016-05-06 11:38:37

标签: android web-services api indexoutofboundsexception autocompletetextview

所以我想实现一个动态AutoCompleteTextView,它将给出要在AutoCompleteTextView的dropDown中填充的列表。

以下是我写的文件和代码。

addLocationEdit = (AutoCompleteTextView) footerView.findViewById(R.id.add_locations_list_edit);

    addLocationEdit.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            new ForLocations().execute(s);
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

    addLocationEdit.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Log.e(Constants.TAG, "LOCATIONS LIST SIZE: " + locationList.size());

            list.add(new AddLocationsBean(locationList.get(position).getId(), locationList.get(position).getName(), locationList.get(position).getDistrict(), locationList.get(position).getState()));
            adapter.notifyDataSetChanged();
            addLocationEdit.setText("");
        }
    });

以下是我正在使用的AsyncTask:

class ForLocations extends AsyncTask<CharSequence, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        locationList = new ArrayList<>();
    }

    @Override
    protected Void doInBackground(CharSequence... params) {

        try {

            CharSequence param = params[0];

            URL url = new URL(Api.LOCATION_URL + "q=" + param);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "application/json");

            inputStream = conn.getErrorStream();
            if (inputStream == null) {
                inputStream = conn.getInputStream();
            }

            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(inputStream), 1000);
            stringBuilder = new StringBuilder();
            stringBuilder.append(reader.readLine() + "\n");

            String line = "0";
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line + "\n");
            }

            inputStream.close();
            locationResponse = stringBuilder.toString();
        } catch (Exception e) {
            Log.e("LOCATION ERROR: ", "LOCATION ERROR: " + e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        try {

            // PARSE JSON

            locationAdapter = new LocationAutoCompleteAdapter(MainActivity.this, locationList);
            addLocationEdit.setAdapter(locationAdapter);
            locationAdapter.notifyDataSetChanged();

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

以下是我正在使用的适配器:

public class LocationAutoCompleteAdapter extends ArrayAdapter<LocationBean> {

Context context;
LayoutInflater inflater;
ArrayList<LocationBean> suggestions, list, tempList;

InputStream inputStream;
StringBuilder stringBuilder;
String locationResponse;

Filter nameFilter = new Filter() {
    @Override
    public CharSequence convertResultToString(Object resultValue) {
        String str = ((LocationBean) resultValue).getName();
        return str;
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        if (constraint != null) {
            suggestions.clear();
            for (LocationBean locationBean : tempList) {
                if (locationBean.getName().toLowerCase().contains(constraint.toString().toLowerCase()) || locationBean.getState().toLowerCase().contains(constraint.toString().toLowerCase()) || locationBean.getDistrict().toLowerCase().contains(constraint.toString().toLowerCase())) {
                    suggestions.add(locationBean);
                }
            }
            FilterResults filterResults = new FilterResults();
            filterResults.values = suggestions;
            filterResults.count = suggestions.size();
            return filterResults;
        } else {
            return new FilterResults();
        }
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        List<LocationBean> filterList = (ArrayList<LocationBean>) results.values;
        if (results != null && results.count > 0) {
            clear();
            for (LocationBean locationBean : filterList) {
                add(locationBean);
                notifyDataSetChanged();
            }
        }
    }
};

public LocationAutoCompleteAdapter(Context context, ArrayList<LocationBean> list) {
    super(context, R.layout.location_autocomplete_list_item, list);
    this.context = context;
    this.list = list;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    tempList = new ArrayList<LocationBean>(list); // this makes the difference.
    suggestions = new ArrayList<LocationBean>();
}

@Override
public LocationBean getItem(int position) {
    return tempList.get(position);
}

@Override
public int getCount() {
    return tempList.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        holder = new ViewHolder();

        convertView = inflater.inflate(R.layout.location_autocomplete_list_item, parent, false);

        holder.name = (TextView) convertView.findViewById(R.id.autcom_name);
        holder.state = (TextView) convertView.findViewById(R.id.autcom_state);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    if (list.get(position).getState().isEmpty()) {
        holder.state.setVisibility(View.GONE);
    } else {
        holder.state.setVisibility(View.VISIBLE);
    }
    holder.name.setText(list.get(position).getName());
    holder.state.setText(list.get(position).getState());

    return convertView;
}

@Override
public Filter getFilter() {
    return nameFilter;
}

class ViewHolder {
    TextView name, state;
}}

当我点击列表项时我得到以下错误:

  

致命异常:mainProcess:varun.com.dynamicautocompletetextview,   PID:27492       ava.lang.IndexOutOfBoundsException:索引0无效,大小为0       at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)       at java.util.ArrayList.get(ArrayList.java:308)       at varun.com.dynamicautocompletetextview.MainActivity $ 3.onItemClick(MainActivity.java:110)       在android.widget.AutoCompleteTextView.performCompletion(AutoCompleteTextView.java:906)       在android.widget.AutoCompleteTextView.-wrap1(AutoCompleteTextView.java)       在android.widget.AutoCompleteTextView $ DropDownItemClickListener.onItemClick(AutoCompleteTextView.java:1202)       在android.widget.AdapterView.performItemClick(AdapterView.java:310)       在android.widget.AbsListView.performItemClick(AbsListView.java:1145)       在android.widget.AbsListView $ PerformClick.run(AbsListView.java:3066)       在android.widget.AbsListView $ 3.run(AbsListView.java:3903)       在android.os.Handler.handleCallback(Handler.java:739)       在android.os.Handler.dispatchMessage(Handler.java:95)       在android.os.Looper.loop(Looper.java:148)       在android.app.ActivityThread.main(ActivityThread.java:5466)       at java.lang.reflect.Method.invoke(Native Method)       在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)       在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

单击列表项时发生 IndexOutOfBoundsException

请说明可能的原因以及解决方案。

随意建议通过Web服务/ API调用实现AutoCompleteTextView填充的任何新方法。

谢谢。

修改 数据正在AutoCompleteTextView中填充。我已经记录并检查了,我可以在dropDown中看到数据本身。

1 个答案:

答案 0 :(得分:1)

所以我找到了解决方案,就在这里。

  1. 请勿覆盖getItemgetCount(如果您使用的是ArrayAdapter)。
  2. 而不是使用list.get(position)使用parent.getItemAtPosition(position)
  3. 如下:

    LocationBean bean =(LocationBean)parent.getItemAtPosition(position);             list.add(new AddLocationsBean(bean.getId(),bean.getName(),bean.getDistrict(),bean.getState()));             adapter.notifyDataSetChanged();             addLocationEdit.setText( “”);

  4. 谢谢。