[Solved] ViewHolder ArrayIndexOutOfBoundsException: length=2; index=2

I try to use two types of views and two types of ViewHolrdes, but received error:

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
        at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6705)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5210)
        at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4368)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
        at android.view.Choreographer.doCallbacks(Choreographer.java:579)
        at android.view.Choreographer.doFrame(Choreographer.java:547)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
        at android.os.Handler.handleCallback(Handler.java:800)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:194)
        at android.app.ActivityThread.main(ActivityThread.java:5371)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        at dalvik.system.NativeStart.main(Native Method)

And here is my adapter:

public class FriendsListAdapterFromKesh extends ArrayAdapter<FriendListEntryItem> {
    List<FriendListEntryItem> friends;
    List<FriendListEntryItem> friendsWithoutPoints;
    Context context;
    private LayoutInflater inflater;
    private LayoutInflater mLayoutInflater;
    private static String ROOT_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + File.separator + ".SleepKeeker/Photos old";
    FriendsTab friendsTab;

    public FriendsListAdapterFromKesh(Context context, final List<FriendListEntryItem> friends, final List<FriendListEntryItem> friendsWithoutPoints) {
        super(context, 0);
        this.context = context;
        inflater = LayoutInflater.from(context);
        this.friendsWithoutPoints = friendsWithoutPoints;
        this.friends = friends;
        friendsTab = new FriendsTab();
        mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void updateList(List<FriendListEntryItem> newlist1, List<FriendListEntryItem> newlist2) {
        friends.clear();
        friends.addAll(newlist1);
        friendsWithoutPoints.clear();
        friendsWithoutPoints.addAll(newlist2);
        this.notifyDataSetChanged();
    }

    public List<FriendListEntryItem> getFriends() {
        return friends;
    }

    @Override
    public int getCount() {
        return friends.size() + friendsWithoutPoints.size();
    }

    public String getIdSocTypeName(int position) {

        if (friends == null || position + 1 >= friends.size()) {
            return "";
        }
        FriendListEntryItem ei = friends.get(position - 1);
        return ei.userId + "," + ei.socType + "," + ei.name;
    }

    static class ViewHolder1 {
        public ImageView image = null;
        public TextView title = null;
        public TextView subtitle = null;
    }

    static class ViewHolder2 {
        public ImageView image;
        public TextView title;
        public TypefacedButton button;
    }

    @Override
    public int getItemViewType(int pos) {
        if (pos < friends.size())
            return 1;
        return 2;
    }

    //@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int viewType = getItemViewType(position);
        ViewHolder1 viewHolder1 = null;
        ViewHolder2 viewHolder2 = null;
        if (convertView == null) {
            if (viewType == 1) {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.list_frnds_item_with_points, parent, false);
                viewHolder1 = new ViewHolder1();
                viewHolder1.title = (TextView) convertView.findViewById(R.id.list_item_title_friend);
                viewHolder1.image = (ImageView) convertView.findViewById(R.id.imageFriendAva);
                viewHolder1.subtitle = (TextView) convertView.findViewById(R.id.list_item_friend_woke_time);
                convertView.setTag(viewHolder1);
            } else {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.list_frnds_item_without_points, parent, false);

                viewHolder2 = new ViewHolder2();
                viewHolder2.title = (TextView) convertView.findViewById(R.id.list_item_title_friend);
                viewHolder2.image = (ImageView) convertView.findViewById(R.id.imageFriendAva);
                viewHolder2.button = (TypefacedButton) convertView.findViewById(R.id.inviteButton);
                viewHolder2.button.setClickListner();
                convertView.setTag(viewHolder2);
            }

        } else {
            if (viewType == 1) {
                viewHolder1 = (ViewHolder1) convertView.getTag();
            } else {
                viewHolder2 = (ViewHolder2) convertView.getTag();
            }
        }
        if (viewType == 1) {
             final FriendListEntryItem ei = friends.get(position);
             viewHolder1.title.setText(ei.name);
             viewHolder1.subtitle.setText(ei.wokeTime);
             File picture = findPicture(ei.name);
             if (picture != null && picture.exists()) {
                    Picasso.with(context).load("file://" + picture.getAbsolutePath()).fit().centerCrop().into(viewHolder1.image);
             }

        } else {
                final FriendListEntryItem ei2 = friendsWithoutPoints.get(position - friends.size());
                viewHolder2.title.setText(ei2.name);
                viewHolder2.button.setFriendItem(ei2);
                File picture = findPicture(ei2.name);
                if (picture != null && picture.exists()) {
                    Picasso.with(context).load("file://" + picture.getAbsolutePath()).fit().centerCrop().into(viewHolder2.image);
                }
         }
      return convertView;
    }
    @Override
    public int getViewTypeCount() {
        return 2;
    }

    private File findPicture(String name) {
        File root = new File(ROOT_DIRECTORY_PATH);
        if (root!= null)
        {
            File[] files = root.listFiles();
            if (files == null)
                return null;

            for (int i = 0; i<files.length; i++) {
                Log.d("qedsds", "" + files[i].getName());
                if (files[i].getName().contains(name))
                    return files[i];
            }
        }
        return null;
    }
}

Error appears when I scroll through the list. But I can not understand why.
I spent a lot of time already to solve this problem, but to no avail

Solution #1:

Replace

@Override
public int getItemViewType(int pos) {
    if (pos < friends.size())
        return 1;
    return 2;
}

by

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

From the Adapter documentation for the method getItemViewType (my emphasis):

Returns

An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, View, ViewGroup). Note: Integers must be in the range 0 to getViewTypeCount() – 1. IGNORE_ITEM_VIEW_TYPE can also be returned.

At the moment, you are returning values 1 and 2 for the view type. You need to return values 0 and 1 instead to satisfy the condition in bold.

Respondent: stkent

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.