Ошибка Android IndexOutOfBoundsException для представления списка фильтрации поиска

Я применил поисковый фильтр к моему SearchView в своей панели SherlockAction. Я реализовал пользовательский фильтр. Когда я набираю любую букву, я получаю сообщение об ошибке

public class PlacesListAdapter extends ArrayAdapter<Place> implements
        Filterable {

    public Context mContext;

    List<Place> mPlaces, orig;

    public PlacesListAdapter(Context context, List<Place> places) {
        super(context, R.layout.list_item_places, places);
        // TODO Auto-generated constructor stub
        this.mPlaces = places;
        this.mContext = context;

        orig = new ArrayList<Place>(places);

    }

    @Override
    public Place getItem(int position) {
        // TODO Auto-generated method stub
        return mPlaces.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if (convertView == null) {
            LayoutInflater viewInflater;
            viewInflater = LayoutInflater.from(getContext());
            convertView = viewInflater.inflate(R.layout.list_item_places, null);

            holder = new ViewHolder();
            holder.placeTitle = (TextView) convertView
                    .findViewById(R.id.place_title);
            holder.placeDistance = (TextView) convertView
                    .findViewById(R.id.place_distance);
            holder.placeCategoryIcon = (ImageView) convertView
                    .findViewById(R.id.place_category_icon);

            convertView.setTag(holder);

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

        holder.placeTitle.setText(mPlaces.get(position).getPlaceName());
        holder.placeDistance.setText(mPlaces.get(position).getPlaceDistance());
        holder.placeCategoryIcon
                .setImageResource(R.drawable.icon_category_hillstation);

        // // Setting Alternative Row Colors
        if (position % 2 == 0) {
            convertView
                    .setBackgroundResource(R.drawable.list_view_places_row_1);
        } else {
            convertView
                    .setBackgroundResource(R.drawable.list_view_places_row_2);
        }

        return convertView;
    }

    static class ViewHolder {
        TextView placeId;

        TextView placeTitle;

        TextView placeDistance;

        ImageView placeCategoryIcon;
    }

    @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub
        return new PlaceFilter();
    }

    private class PlaceFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint){
            FilterResults oReturn = new FilterResults();
            ArrayList<Place> results = new ArrayList<Place>();
            if (orig == null)
                orig = mPlaces;
            if (constraint != null) {
                if (orig != null && orig.size() > 0) {
                    for (Place g : orig) {
                        if (g.getPlaceName()
                                .toLowerCase()
                                .startsWith(constraint.toString().toLowerCase()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            mPlaces = (ArrayList<Place>) results.values;
            notifyDataSetChanged();
        }

    }

}

ОШИБКА

12-26 17:24:43.900: E/AndroidRuntime(18693): FATAL EXCEPTION: main
12-26 17:24:43.900: E/AndroidRuntime(18693): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
12-26 17:24:43.900: E/AndroidRuntime(18693):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at java.util.ArrayList.get(ArrayList.java:304)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at com.m7.nomad.PlacesListAdapter.getView(PlacesListAdapter.java:68)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.AbsListView.obtainView(AbsListView.java:2193)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.ListView.makeAndAddView(ListView.java:1774)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.ListView.fillDown(ListView.java:672)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.ListView.fillSpecific(ListView.java:1330)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.ListView.layoutChildren(ListView.java:1603)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.AbsListView.onLayout(AbsListView.java:2044)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.View.layout(View.java:11418)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewGroup.layout(ViewGroup.java:4224)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:925)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.View.layout(View.java:11418)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewGroup.layout(ViewGroup.java:4224)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.View.layout(View.java:11418)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewGroup.layout(ViewGroup.java:4224)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.View.layout(View.java:11418)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewGroup.layout(ViewGroup.java:4224)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.View.layout(View.java:11418)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewGroup.layout(ViewGroup.java:4224)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1628)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2585)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.os.Looper.loop(Looper.java:137)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at android.app.ActivityThread.main(ActivityThread.java:4507)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at java.lang.reflect.Method.invokeNative(Native Method)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at java.lang.reflect.Method.invoke(Method.java:511)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
12-26 17:24:43.900: E/AndroidRuntime(18693):    at dalvik.system.NativeStart.main(Native Method)

Ошибка

Это указывает на

holder.placeTitle.setText(mPlaces.get(position).getPlaceName());

person Harsha M V    schedule 26.12.2012    source источник


Ответы (4)


При отладке вы увидите, что mPlaces.getSize() равно 1, и при попытке доступа к элементу в позиции 1 вы получите исключение ArrayOutOfBounds.

в вашем ArrayList что-то не так, и, вероятно, в нем нет всех данных, которые вы пытаетесь получить.

person thepoosh    schedule 26.12.2012
comment
где я должен начать изучать отладку? список заполняется сразу при загрузке. это происходит только тогда, когда я пытаюсь ввести и отфильтровать его - person Harsha M V; 26.12.2012
comment
попробуйте поставить точку останова в начале getView и посмотрите, куда это вас приведет - person thepoosh; 26.12.2012
comment
когда я что-то набираю - это напрямую не дает результатов. pastebin.com/7q4dQC4B странно :( - person Harsha M V; 26.12.2012
comment
Я бы убедился, что в конструкторе mPlaces.size() больше 1, а затем отладил бы getView и посмотрел, что пойдет не так. - person thepoosh; 26.12.2012
comment
Кроме того, после просмотра ваших изменений pastebin я заметил, что вы больше не сравниваете ограничение с g.getPlaceName(), что было намерением в исходном сообщении, поэтому оно должно быть item.getPlaceName(), если вы следовали тем же данным модель .. спасибо за размещение всего этого! - person whyoz; 23.01.2014

Попробуйте закрыть эту линию

holder.placeTitle.setText(mPlaces.get(position).getPlaceName());

*со следующим условием *

if(position < mPlaces.size() && holder.placeTitle != null)
  holder.placeTitle.setText(mPlaces.get(position).getPlaceName());

ИЗМЕНИТЬ:

Вот мой небольшой реализованный фрагмент:

@Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder;

            if (convertView == null) {
                LayoutInflater viewInflater;
                viewInflater = getLayoutInflater();
                convertView = viewInflater.inflate(R.layout.listview, null);

                holder = new ViewHolder();
                convertView.setTag(holder);

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

                // Try here first
                holder.textview = (TextView) convertView.findViewById(R.id.TextView01);
                holder.imageview = (ImageView) convertView.findViewById(R.id.ImageView01);
            }

            // Try here second
            // holder.textview = (TextView)convertView.findViewById(R.id.TextView01);
            // holder.imageview = (ImageView)convertView.findViewById(R.id.ImageView01);

            if (holder.textview != null && position < data_text.length)
                holder.textview.setText(data_text[position]);
            if (holder.imageview != null && position < data_image.length)
                holder.imageview.setImageResource(data_image[position]);

            return convertView;
        }

Вы можете заменить его своими переменными.

Спасибо.

person Pratik Sharma    schedule 26.12.2012
comment
я пробовал это. но теперь я получаю несколько записей строк в случайном порядке - person Harsha M V; 26.12.2012
comment
@HarshaMV попробуйте удалить такие объявления holder.placeTitle = (TextView) convertView.findViewById(R.id.place_title); из if до else части в getView методе. А если не получится то выложи в сторону после if..else. - person Pratik Sharma; 26.12.2012
comment
не понял тебя. не могли бы вы объяснить - person Harsha M V; 26.12.2012
comment
@HarshaMV посмотрите отредактированное решение, которое я опубликовал. Я показал, в каких местах удобно объявлять элементы управления держателем. - person Pratik Sharma; 26.12.2012
comment
Да. я пропустил метод getCount. только что добавил и работает :( - person Harsha M V; 26.12.2012

Попробуйте этот код для своих приложений,

if (g.getPlaceName().toLowerCase().contains(constraint.toString().toLowerCase())){
    results.add(g);
}
person NAP Developer    schedule 26.12.2012
comment
я хочу использовать, в частности, .startsWith - person Harsha M V; 26.12.2012

Если кому-то нужен код для SearchView в настраиваемой панели действий, которая входит в вашу активность (или в данном случае ListFragment), вот он:

    ActionBar actionBar = getActivity().getActionBar();
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
    actionBar.setDisplayShowHomeEnabled(true);
    actionBar.setCustomView(R.layout.your_bar);
    SearchView groupSV = (SearchView)actionBar.getCustomView().findViewById(R.id.groupSV);
    groupSV.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText) {
            Log.d(TAG,"onQueryTextChange");
            ListViewFragment.adapter.getFilter().filter(newText);
            return true;
        }
        @Override
        public boolean onQueryTextSubmit(String query) {
            Log.d(TAG,"onQueryTextSubmit");
            //ListViewFragment.adapter.getFilter().filter(query);
            return true;
        }
    });

Вам нужно будет объявить свой адаптер статическим, как это в вашем ListViewFragment:

public static ArrayAdapter<Your_obj> adapter = null;

public class ListViewFragment extends ListFragment implements OnItemClickListener {
    //...//
}

Кроме того, обязательно ознакомьтесь с отредактированным кодом OP по его ссылке: РЕДАКТИРОВАНИЕ PASTEBIN

person whyoz    schedule 23.01.2014