skip to Main Content

I started using Retrofit instead of Volley for the sake of speed and easy of implementation.

For some context I’m using a BottomNavigationBar with Fragments and I can’t display first in my application (after the splash screen) the Fragment which loads the data with Retrofit. If I display another Fragment and I search for my Fragment in question everything works fine.

My code for load data in fragment

binding.recyclerViewUser.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
binding.recyclerViewUser.setOverScrollMode(View.OVER_SCROLL_NEVER);
usersAdapter = new UsersAdapter(mContext, usersList, 4);
binding.recyclerViewUser.setAdapter(usersAdapter);

Call<List<UsersModel>> getUersData = RetrofitClient.getInstance().getApi().getUsersData();
getUersData.enqueue(new Callback<>() {
  @Override
  public void onResponse(@NonNull Call<List<UsersModel>> call, @NonNull Response<List<UsersModel>> response) {
    usersList = response.body();
    usersAdapter.setUsersList(usersList);

    Log.d("Retrofit success", "Yeah!");

    long requestTime = response.raw().sentRequestAtMillis();
    long responseTime = response.raw().receivedResponseAtMillis();
    long apiTime =  responseTime - requestTime;

    Log.d("Retrofit time", apiTime + "ms");
  }

  @Override
  public void onFailure(@NonNull Call<List<UsersModel>> call, @NonNull Throwable t) {
    Log.d("Retrofit error", t.getMessage());
  }
});

Now my error when I want to load my Fragment first in my application

2022-08-09 10:03:18.944 7422-7422/com.package.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.package.app, PID: 7422
    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.package.app.adapter.UsersAdapter.onBindViewHolder(UsersAdapter.java:49)
        at com.package.app.adapter.UsersAdapter.onBindViewHolder(UsersAdapter.java:23)

The error of corresponds to nothing, first java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 is already defined in this line usersAdapter = new UsersAdapter(mContext, usersList, 4); the int of 4 returns the size

And the other error at com.package.app.adapter.UsersAdapter.onBindViewHolder(UsersAdapter.java:49) matches this line holder.name.setText(usersList.get(position).getName()); but I can load my RecyclerView when it’s not showing in first position in my application.

I show you my UsersAdapter, maybe I missed a few things but everything seems correct to me

public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.UsersHolder> {
  Context mContext;
  List<UsersModel> usersModel;
  int size;

  public UsersAdapter(Context mContext, List<UsersModel> usersModel, int size) {
      this.mContext = mContext;
      this.usersModel = usersModel;
      this.size = size;
  }

  public void setUsersList(List<UsersModel> usersModel) {
      this.usersModel = usersModel;
      notifyDataSetChanged();
  }

  @NonNull
  @Override
  public UsersAdapter.UsersHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
      View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_users, parent, false);
      return new UsersHolder(view);
  }

  @Override
  public void onBindViewHolder(@NonNull UsersAdapter.UsersHolder holder, int position) {
      holder.name.setText(usersModel.get(position).getName());
      holder.description.setText(usersModel.get(position).getDescription());
      Glide.with(holder.itemView.getContext().getApplicationContext()).load(usersModel.get(position).getLogo()).into(holder.logo);
  }

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

  public static class UsersHolder extends RecyclerView.ViewHolder {
      private final ImageView logo;
      private final TextView name, description;

      public UsersHolder(@NonNull View itemView) {
          super(itemView);
          logo = itemView.findViewById(R.id.logo);
          name = itemView.findViewById(R.id.title);
          description = itemView.findViewById(R.id.description);
      }
  }
}

If anyone can help me I would be very grateful

3

Answers


  1. you can try to create adapter and assign list after filling the list. You can try the following code;

    binding.recyclerViewUser.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
    binding.recyclerViewUser.setOverScrollMode(View.OVER_SCROLL_NEVER);
    
    
    Call<List<UsersModel>> getUersData = RetrofitClient.getInstance().getApi().getUsersData();
    getUersData.enqueue(new Callback<>() {
        @Override
        public void onResponse(@NonNull Call<List<UsersModel>> call, @NonNull
                Response<List<UsersModel>> response) {
            usersList = response.body();
            usersAdapter = new UsersAdapter(mContext, usersList, 4);
            binding.recyclerViewUser.setAdapter(usersAdapter);
    
            Log.d("Retrofit success", "Yeah!");
    
            long requestTime = response.raw().sentRequestAtMillis();
            long responseTime = response.raw().receivedResponseAtMillis();
            long apiTime =  responseTime - requestTime;
    
            Log.d("Retrofit time", apiTime + "ms");
        }
    
        @Override
        public void onFailure(@NonNull Call<List<UsersModel>> call, @NonNull Throwable t){
            Log.d("Retrofit error", t.getMessage());
        }
    });
    
    Login or Signup to reply.
  2. try this

    @Override
      public int getItemCount() {
          return usersModel.size();
      }
    
    Login or Signup to reply.
  3. Your Adapter created when your list is empty, you can change your code like this:

    binding.recyclerViewUser.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
    binding.recyclerViewUser.setOverScrollMode(View.OVER_SCROLL_NEVER);
    
    Call<List<UsersModel>> getUersData = RetrofitClient.getInstance().getApi().getUsersData();
    getUersData.enqueue(new Callback<>() {
      @Override
      public void onResponse(@NonNull Call<List<UsersModel>> call, @NonNull Response<List<UsersModel>> response) {
        usersList = response.body();
        usersAdapter = new UsersAdapter(mContext, usersList, 4);
        binding.recyclerViewUser.setAdapter(usersAdapter);
        usersAdapter.setUsersList(usersList);
    
        Log.d("Retrofit success", "Yeah!");
    
        long requestTime = response.raw().sentRequestAtMillis();
        long responseTime = response.raw().receivedResponseAtMillis();
        long apiTime =  responseTime - requestTime;
    
        Log.d("Retrofit time", apiTime + "ms");
      }
    
      @Override
      public void onFailure(@NonNull Call<List<UsersModel>> call, @NonNull Throwable t) {
        Log.d("Retrofit error", t.getMessage());
      }
    });
    

    Suggest:
    you don’t need put your list in constructor of Adapter, setUserList method did it for you

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search