Search code examples
javaandroidandroid-recyclerviewadapter

attempt to display details in another Activity "java.lang.IndexOutOfBoundsException: Index: 0, Size: 0"


I'm trying to use OnItemClick to display details in a user profile page and I still have this error:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at fr.ousoft.suiviemedsbox.ScrollingActivity.OnItemClick(**ScrollingActivity.java:102**)
        at fr.ousoft.suiviemedsbox.UsersAdapter$AdapterVH$1.onClick(**UsersAdapter.java:115**)

Here is my Activity code

    public class ScrollingActivity extends AppCompatActivity implements UsersAdapter.OnItemClickListener {

    public static final String EXTRA_CREATOR_NOM = "Nom";
    public static final String EXTRA_CREATOR_PRENOM = "Prenom";
    public static final String EXTRA_CREATOR_TEL = "Tel";
    public static final String EXTRA_CREATOR_EMAIL = "Email";
    public static final String EXTRA_CREATOR_ETABLISSEMENT = "Etablissement";
    public static final String EXTRA_CREATOR_TYPE = "Type";
    public static final String EXTRA_CREATOR_ACTIVE = "Active";

    RecyclerView recyclerView;
    ApiInterface apiInterface;
    UsersAdapter usersAdapter;
    ArrayList<User> mListe = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scrolling);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        CollapsingToolbarLayout toolBarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
        toolBarLayout.setTitle(getTitle());

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(ScrollingActivity.this, RegisterActivity.class);
                startActivity(intent);
            }
        });
        recyclerView = findViewById(R.id.recyclerViewList);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

        usersAdapter = new UsersAdapter();

        fetchUsers();
    }

    public void fetchUsers(){
        apiInterface = ApiClient.getRetrofitInstance().create(ApiInterface.class);
        Call<List<User>> call = apiInterface.getAllUsers();

        call.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                if (response.isSuccessful()){
                    List<User> users = response.body();
                    usersAdapter.setData(users);
                    usersAdapter.setOnItemClickListener(ScrollingActivity.this);

                    recyclerView.setAdapter(usersAdapter);

                }
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {
                Log.e("success", t.getLocalizedMessage());
            }
        });
    }

    @Override
    public void OnItemClick(int position) {
        Intent detailIntent = new Intent(this,DetailActivity.class);
        User clickedUser = mListe.get(position);

        detailIntent.putExtra(EXTRA_CREATOR_NOM, clickedUser.getNom());
        detailIntent.putExtra(EXTRA_CREATOR_PRENOM, clickedUser.getPrenom());
        detailIntent.putExtra(EXTRA_CREATOR_TEL, clickedUser.getTel());
        detailIntent.putExtra(EXTRA_CREATOR_EMAIL, clickedUser.getEmail());
        detailIntent.putExtra(EXTRA_CREATOR_ETABLISSEMENT, clickedUser.getEtablissement());
        detailIntent.putExtra(EXTRA_CREATOR_TYPE, clickedUser.getType());
        detailIntent.putExtra(EXTRA_CREATOR_ACTIVE, clickedUser.getActive());

        startActivity(detailIntent);
    }
}

Adapter:

    public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.AdapterVH>{


    private List<User> userList;
    private Context context;
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void OnItemClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener listener){
        mListener = listener;
    }

    public UsersAdapter(){
    }

    public void setData(List<User> userList){
        this.userList = userList;
        notifyDataSetChanged();
    }
    @NonNull
    @Override
    public AdapterVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        return new UsersAdapter.AdapterVH(LayoutInflater.from(context).inflate(R.layout.item_list,parent,false));
    }

    @SuppressLint("ResourceAsColor")
    @Override
    public void onBindViewHolder(@NonNull AdapterVH holder, int position) {
        User user = userList.get(position);

        String nom = user.getNom();
        String email = user.getEmail();
        String etab = user.getEtablissement();
        String active = user.getActive();
        String prenom = user.getPrenom();

        holder.txtNom.setText(nom);
        if (nom == null) {
            holder.txtNom.setText("Aucun Nom");
        }
        holder.txtEmail.setText(email);
        if (email == null) {
            holder.txtEmail.setText("Aucun Email");
        }
        holder.txtEttab.setText(etab);
        if (etab == null) {
            holder.txtEttab.setText("Aucun Etablissement");
        }
        holder.txtPrenom.setText(prenom);
        if (prenom == null) {
            holder.txtPrenom.setText("Aucun Prenom");
        }
        if (active == null) {
            holder.ActiveDesactive.setText(R.string.desact);
        }else {
            holder.ActiveDesactive.setText(R.string.activ);
        }
    }

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


    public class AdapterVH extends RecyclerView.ViewHolder{

        TextView txtNom;
        TextView txtPrenom;
        TextView txtEmail;
        TextView txtEttab;
        Button ActiveDesactive;

        public AdapterVH(@NonNull View itemView) {
            super(itemView);

            txtNom = itemView.findViewById(R.id.NomUser);
            txtPrenom = itemView.findViewById(R.id.PrenomUser);
            txtEmail = itemView.findViewById(R.id.EmailUser);
            txtEttab = itemView.findViewById(R.id.EtabUser);
            ActiveDesactive = itemView.findViewById(R.id.ActiveDesavtive);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mListener != null){
                        int positions = getAdapterPosition();
                        if (positions != RecyclerView.NO_POSITION){
                            mListener.OnItemClick(positions);
                        }
                    }
                }
            });
        }

    }
}

Solution

  • You never fill mListe with any content. If you search for mListe. the only match you get is mListe.get. You have no invocations of mListe.add or mListe.addAll. What you do instead is set a list from a response directly into the adapter:

    if (response.isSuccessful()){
        // Here is the error
        List<User> users = response.body();
        
        usersAdapter.setData(users);
        usersAdapter.setOnItemClickListener(ScrollingActivity.this);
    
        recyclerView.setAdapter(usersAdapter);
    }
    

    What should be done instead is the following:

    1. Clear mListe from any previous content;
    2. Fill with new content;
    3. Set new data to the adapter.
    if (response.isSuccessful()){
        mListe.clear();
        mListe.addAll(response.body());
        
        usersAdapter.setData(mListe);
    }
    

    I have removed a few lines from this if-statement and moved them into the onCreate. They should be called only once, there is no benefit setting the same adapter and click listener if you call fetchUsers() again.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
    
        usersAdapter = new UsersAdapter();
        usersAdapter.setOnItemClickListener(this);
        recyclerView.setAdapter(usersAdapter);
     
        fetchUsers();
    }