Thiago
Thiago

Reputation: 13302

recyclerview onclicklistener java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

when I dynamic remove an item, or when I refresh the adapter(swipe to fresh) i get these erros:

recyclerview onclicklistener java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

Really can't figure out why this is happening, Really Appreciate any feed back.

MainActivity:

adapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                GroupModel selectedList = mGroupModels.get(position);

                if (selectedList != null) {

                    Log.d(TAG, "setAdpterListner > view.getId: " + view.getId() +
                                    " | P: " + position +
                                    " | data ID: " + selectedList.getGroupName()
                            //" | viewID: " + viewID
                    );


                    Intent intent = new Intent(this, DetailsActivity.class);
                    String listId = selectedList.getGroupID();
                    String listName = selectedList.getGroupName();
                    intent.putExtra(Constant.KEY_LIST_ID, listId);
                    intent.putExtra(Constant.KEY_LIST_NAME, listName);
                    startActivity(intent);
                }
            }
        });

Adapter:

public class GroupListAdapter extends RecyclerView.Adapter<GroupListAdapter.StatusViewHolder> {

    Context context;
    private List<GroupModel> mGroupModels;
    private static OnItemClickListener listener;




    public GroupListAdapter(Context context, List<GroupModel> groupList) {
        this.context = context;
        this.mGroupModels = groupList;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        GroupListAdapter.listener = listener;
    }




    @Override
    public StatusViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_group_list, parent, false);
        return new StatusViewHolder(view);
    }


    @Override
    public void onBindViewHolder(StatusViewHolder holder, int position) {

        final GroupModel data = mGroupModels.get(position);

        holder.text_view_list_name.setText(data.getGroupName());


    }//end onBindViewHolder


    @Override
    public int getItemCount() {
        return mGroupModels.size();
    }






    public class StatusViewHolder extends RecyclerView.ViewHolder {

        public TextView text_view_list_name;
        public TextView created_by;



        public StatusViewHolder(final View itemView) {
            super(itemView);

            text_view_list_name = (TextView) itemView.findViewById(R.id.text_view_list_name);
            created_by = (TextView) itemView.findViewById(R.id.created_by);


            // Setup the click listener
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null)
                        listener.onItemClick(itemView, getLayoutPosition());
                }
            });


        }
    }//end StatusViewHolder


}//end GroupListAdapter

UPDATE:

I taken into consideration Yurii Tsap Feedback. I check the code again. I think the problem is somewhere below:

Whenever I swipe to Fresh, and If i click on the list straight way, the app Crash with the error from above.

 mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Refresh items
                mRecyclerView.invalidate();
                adapter = null;

                initGetGroupList();
                mSwipeRefreshLayout.setRefreshing(false);
            }
        });

In the API call

...
   GroupModel groupModel = new GroupModel(groupID, groupName, groupCreatedBy);
                                mGroupModels.add(groupModel);
                            }


                            updateUI(true);

                            if (adapter == null) {
                                adapter = new GroupListAdapter(MainActivity.this, mGroupModels);
                                mRecyclerView.setAdapter(adapter);
                                setAdapterListener(adapter);
                            }

Upvotes: 1

Views: 1060

Answers (3)

user3623824
user3623824

Reputation: 193

your code have alot of problem i will explain my way to handle recycle view

very simple adapter

package com.pentavalue.ongo.transportway.adapter;

import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;


import com.pentavalue.ongo.R;
import com.pentavalue.ongo.Utilts.ImageLoaderHelper;
import com.pentavalue.ongo.register.model.Vechiles;
import com.pentavalue.ongo.widget.ArabicTextView;

import java.util.ArrayList;

/**
 * Created by hamada on 19/09/2015.
 */
public class TransportTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public LayoutInflater inflater = null;

    Activity activity;
    ArrayList<Vechiles> vechileList;
    ImageLoaderHelper imageLoaderHelper;

    public TransportTypeAdapter(Activity activity, ArrayList<Vechiles> vechileList) {
        this.activity = activity;
        this.vechileList = vechileList;
        imageLoaderHelper = new ImageLoaderHelper(activity, null);
        inflater = LayoutInflater.from(activity);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View vi = inflater.inflate(R.layout.single_transport_item, parent, false);
        RecyclerView.ViewHolder vh = new VechileListHolder(vi);
        return vh;

    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int pos) {

        VechileListHolder mHolder = (VechileListHolder) viewHolder;
        mHolder.renderDate(vechileList.get(pos));

    }


    @Override
    public int getItemCount() {
        if (vechileList != null)
            return this.vechileList.size();
        else
            return 0;
    }


    public class VechileListHolder extends RecyclerView.ViewHolder implements
        View.OnClickListener {
        ArabicTextView vecName;
        RelativeLayout img_layout;
        ProgressBar progress;
        ImageView imgView;

        public VechileListHolder(View vi) {
            super(vi);
            vi.setOnClickListener(this);
            img_layout = (RelativeLayout) vi.findViewById(R.id.img_layout);
            vecName = (ArabicTextView) vi.findViewById(R.id.TVVecName);
            progress = (ProgressBar) vi.findViewById(R.id.progress);
            imgView = (ImageView) vi.findViewById(R.id.imgView);


        }

        public void renderDate(Vechiles item) {
            imageLoaderHelper.loadImage(imgView, progress, item.getImg());
            vecName.setText(item.getVecName());

        }

        @Override
        public void onClick(View v) {
            if (mItemClickListener != null)
                mItemClickListener.onItemClickListener(getPosition(), v);
        }
    }


    public void setOnItemClickListener(ItemClickListener itemClick) {
        this.mItemClickListener = itemClick;
    }

    public ItemClickListener mItemClickListener;

    public interface ItemClickListener {
        public void onItemClickListener(int pos, View v);
    }

    public void updateList(ArrayList<Vechiles> vechileList) {
        this.vechileList = vechileList;
        notifyDataSetChanged();
    }


 public void removeItem(int pos){
     this.vechileList.remove(pos);
    notifyItemRemoved(pos);
    }

    }

and in Fragment or activity can @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState);

        initListView();

}

private void initRecycleView(){
 listView = (RecyclerView) v.findViewById(R.id.listView);
        listView.getItemAnimator().setAddDuration(1000);
        listView.getItemAnimator().setChangeDuration(1000);
        listView.getItemAnimator().setMoveDuration(1000);
        listView.getItemAnimator().setRemoveDuration(1000);
        listView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
        listView.setAdapter(new TransportTypeAdapter(getActivity(), vecList));
}

then after data back from API can update adapter with new data by use method update

((VechileListHolder ) listView.getAdapter).updateList( vechileList);

in case went to remove any item by using Pos can do call method that in adapter removeItem(pos)

((VechileListHolder ) listView.getAdapter).removeItem(1);

hope this code help you

Upvotes: 0

Yurii Tsap
Yurii Tsap

Reputation: 3754

The problem is definitely not in the static listener. And also the listener is just an interface callback(related to the comment above) not a AdapterView.OnItemClickListener(). I think the problem is somewhere behind this code, maybe you are clearing the item list somewhere else or something like that?
And also as for me in your case it's better to use getAdapterPosition() instead of getLayoutPosition(). As mentioned in docs :

If LayoutManager needs to call an external method that requires the adapter position of the item, it can use getAdapterPosition() or RecyclerView.Recycler.convertPreLayoutPositionToPostLayout(int).

Upvotes: 1

Muhammad Younas
Muhammad Younas

Reputation: 1601

Make OnItemClickListener non static .Like

private OnItemClickListener listener;

Upvotes: 0

Related Questions