Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayIndexOutOfBoundsException with ArrayAdapter with filter

I am getting an ArrayIndexOutOfBoundsException with the given below custom implementation of an ArrayAdapter with filtering enabled. I see the filtering code returning the correct resultset, but when view is rendered after filtering, I get an exception. What am I doing wrong here. Any help is appreaciated.

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;
import com.syntrio.iwm.act.R;

public class IWMArrayAdapter<T> extends ArrayAdapter<T>{

    Activity activity;
    List<T> mItems;
    String[] icons;
    boolean isArrowNeeded=false;
    boolean isIconNeeded=false;
    private ItemsFilter mFilter;


    public IWMArrayAdapter(Activity context,List<T> items) {
        super(context, R.layout.item_row,items);
        activity=context;
        mItems=items;
    }

    public void setIcons(String[] iconList){
        if(iconList!=null && iconList.length>0){
            icons=iconList;
            isIconNeeded=true;
        }
    }
    public void setArrowNeeded(){
        isArrowNeeded=true;
    }

    @Override
    public View getView(int position, View convertView,ViewGroup parent) {
        View row = convertView;
        if (row == null) {
            LayoutInflater inflater = activity.getLayoutInflater();
            row = inflater.inflate(R.layout.item_row_array, parent, false);
        }
        TextView label = (TextView) row.findViewById(R.id.label);
        label.setText(mItems.get(position).toString());
        ImageView icon;
        ImageView arrow;
        if(isIconNeeded){
            icon = (ImageView) row.findViewById(R.id.row_image);
            if(icons.length==1){
                icon.setImageResource(activity.getResources().getIdentifier(icons[0], "drawable", "com.syntrio.iwm.act"));
            }
            else{
                icon.setImageResource(activity.getResources().getIdentifier(icons[position], "drawable", "com.syntrio.iwm.act"));
            }
            icon.setVisibility(View.VISIBLE);
        }
        if(isArrowNeeded){
            arrow = (ImageView) row.findViewById(R.id.row_arrow);
            arrow.setImageResource(activity.getResources().getIdentifier("arrow", "drawable", "com.syntrio.iwm.act"));
            arrow.setVisibility(View.VISIBLE);
        }


        return (row);
    }

    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ItemsFilter();
        }
        return mFilter;

    }

    private class ItemsFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            // We implement here the filter logic
            if (constraint == null || constraint.length() == 0) {
                // No filter implemented we return all the list
                results.values = mItems;
                results.count = mItems.size();
            }
            else {
                // We perform filtering operation
                List<T> itemsList = new ArrayList<T>();

                for (T t : mItems) {
                    if (t.toString().toUpperCase().startsWith(constraint.toString().toUpperCase()))
                        itemsList.add(t);
                }

                results.values = itemsList;
                results.count = itemsList.size();

            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            // Now we have to inform the adapter about the new list filtered
            if (results.count == 0){
                notifyDataSetInvalidated();
            }
            else {

                List<T> lst = (List<T>)results.values;
                 List<T> itemsList = new ArrayList<T>(lst);
                 //this.items=mItems;
                mItems =itemsList;              
                notifyDataSetChanged();
            }

        }

    }

}

Exception is :

03-24 16:52:11.608: E/AndroidRuntime(947): FATAL EXCEPTION: main
03-24 16:52:11.608: E/AndroidRuntime(947): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
03-24 16:52:11.608: E/AndroidRuntime(947):  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
03-24 16:52:11.608: E/AndroidRuntime(947):  at java.util.ArrayList.get(ArrayList.java:311)
03-24 16:52:11.608: E/AndroidRuntime(947):  at com.syntrio.iwm.IWMArrayAdapter.getView(IWMArrayAdapter.java:50)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.AbsListView.obtainView(AbsListView.java:1409)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.ListView.measureHeightOfChildren(ListView.java:1216)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.ListView.onMeasure(ListView.java:1127)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.View.measure(View.java:8313)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.View.measure(View.java:8313)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.View.measure(View.java:8313)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:531)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.View.measure(View.java:8313)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.View.measure(View.java:8313)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.View.measure(View.java:8313)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.ViewRoot.performTraversals(ViewRoot.java:839)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.os.Looper.loop(Looper.java:130)
03-24 16:52:11.608: E/AndroidRuntime(947):  at android.app.ActivityThread.main(ActivityThread.java:3683)
03-24 16:52:11.608: E/AndroidRuntime(947):  at java.lang.reflect.Method.invokeNative(Native Method)
03-24 16:52:11.608: E/AndroidRuntime(947):  at java.lang.reflect.Method.invoke(Method.java:507)
03-24 16:52:11.608: E/AndroidRuntime(947):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-24 16:52:11.608: E/AndroidRuntime(947):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-24 16:52:11.608: E/AndroidRuntime(947):  at dalvik.system.NativeStart.main(Native Method)

Update : added exception

like image 481
sab Avatar asked Mar 24 '13 17:03

sab


1 Answers

You need to implement the getCount method within your custom ArrayAdapter. The ListView invokes that method on its adapter to find out how many items it will display. You need something like this:

public int getCount () {
    return mItems.size ();
}
like image 191
Shade Avatar answered Oct 06 '22 11:10

Shade