Home > Net >  Unable to display a RecyclerView with Retrofit in first fragment
Unable to display a RecyclerView with Retrofit in first fragment

Time:08-09

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

CodePudding user response:

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

CodePudding user response:

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());
    }
});

CodePudding user response:

try this

@Override
  public int getItemCount() {
      return usersModel.size();
  }
  • Related