Jay
Jay

Reputation: 5084

Android Adapter crashing with ArrayIndexOutOfBoundsException

I understand that this exception describes a situation where we are trying to access an element which does not exist/exceeds the size of the array. However in my case, I cannot exactly point out where this originates from.

The exception is vivid and does not describe any line of code where the problem may be arising from.

I also have a Filter inside the adapter since I need a search functionality to filter items in the arraylist

Adapter class:

public class SearchAdapter extends BaseAdapter {

    private Activity activity;
    private static LayoutInflater inflater = null;
    ArrayList<Event> resultList = new ArrayList<>();
    private ArrayList<Event> arraylist = null;

    public SearchAdapter(Activity context, ArrayList<Event> resultList) {
        this.activity = context;
        this.resultList = resultList;
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.arraylist = new ArrayList<Event>();
        this.arraylist.addAll(resultList);
    }

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

    @Override
    public Event getItem(int i) {
        return resultList.get(i);
    }

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

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (position < resultList.size())
            return 0;
        return 1;
    }

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

        View view = convertView;
        Holder holder = new Holder();
        final Event result = getItem(position);

        if (view == null) {
            view = inflater.inflate(R.layout.row_single_search_row, null);

            holder.parent = (RelativeLayout) view.findViewById(R.id.parent);
            holder.name = (TextView) view.findViewById(R.id.name);
            holder.details = (TextView) view.findViewById(R.id.details);

            view.setTag(holder);

        } else {
            holder = (Holder) view.getTag();
        }

        holder.name.setText(result.getTitle());
        holder.details.setText(result.getDescriptions());

        return view;
    }

    public static class Holder {
        RelativeLayout parent;
        TextView name, details;
    }

    //I believe this 'might' be where the problem originates
    //This method is used to act as a filter that filters/searches items when text is entered to a EditText in the main activity
    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        resultList.clear();
        if (charText.length() == 0) {
            resultList.addAll(arraylist);
        } else {
            for (Event wp : arraylist) {
                if (wp.getTitle().toLowerCase(Locale.getDefault()).contains(charText)) {
                    resultList.add(wp);
                }
            }
        }
        notifyDataSetChanged();
    }

}

Main Activity's OnCreate:

searchBox.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                if (adapter != null && searchListView.getAdapter() != null) {
                    adapter.filter(s.toString());
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {

            }

            @Override
            public void afterTextChanged(Editable s) {
            }
 });

Error I get:

java.lang.ArrayIndexOutOfBoundsException: length=3; index=3
    at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:8948)
    at android.widget.ListView.layoutChildren(ListView.java:1681)
    at android.widget.AbsListView.onLayout(AbsListView.java:2723)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:613)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1767)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:433)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
    at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:3178)
    at android.view.View.layout(View.java:17938)
    at android.view.ViewGroup.layout(ViewGroup.java:5812)
    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2666)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7397)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
    at android.view.Choreographer.doCallbacks(Choreographer.java:695)
    at android.view.Choreographer.doFrame(Choreographer.java:631)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:158)
    at android.app.ActivityThread.main(ActivityThread.java:7225)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Upvotes: 0

Views: 521

Answers (3)

Ashutosh Srivastava
Ashutosh Srivastava

Reputation: 103

You can change in your filter method like this
if(charText==0){
    this.resultList=arrayList; //that is your original list
}else{
    resultList = new ArrayList<Event>();
    for (Event wp : arraylist) {
                    if (wp.getTitle().toLowerCase(Locale.getDefault()).contains(charText)) {
                        resultList.add(wp);
                    }
                }
this.resultList=resultList;
    }
notifyDataSetChanged();

Upvotes: 0

OneCricketeer
OneCricketeer

Reputation: 191728

I think you are getting the wrong list here

@Override
public Event getItem(int i) {
    return resultList.get(i);
}

Determine which list you really need

ArrayList<Event> resultList = new ArrayList<>();
private ArrayList<Event> arraylist = null;

Because you only load one of them

this.arraylist = new ArrayList<Event>();
this.arraylist.addAll(resultList);

In other words, careful with this.

this.resultList = resultList;

Anytime you edit that list externally, outside this adapter, you are editing the same reference within the adapter, which could cause your error

Upvotes: 1

Sasi Kumar
Sasi Kumar

Reputation: 13348

you are not properly assign value in arraylist. Use

 this.arraylist = new ArrayList<>(resultList);

instead of

 this.arraylist = new ArrayList<Event>();

remove this.arraylist.addAll(resultList);

Upvotes: 0

Related Questions