简体   繁体   English

无法在第一个片段中显示带有 Retrofit 的 RecyclerView

[英]Unable to display a RecyclerView with Retrofit in first fragment

I started using Retrofit instead of Volley for the sake of speed and easy of implementation.为了速度和易于实施,我开始使用 Retrofit 而不是 Volley。

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.在某些情况下,我使用带有 Fragments 的 BottomNavigationBar,我无法在我的应用程序中(在启动屏幕之后)首先显示使用 Retrofit 加载数据的 Fragment。 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);错误对应什么都没有,首先java.lang.IndexOutOfBoundsException: Index: 0, Size: 0在这一行已经定义usersAdapter = new UsersAdapter(mContext, usersList, 4); the int of 4 returns the size int of 4 返回大小

And the other error at com.package.app.adapter.UsersAdapter.onBindViewHolder(UsersAdapter.java:49) matches this line holder.name.setText(usersList.get(position).getName()); 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.但是当我的应用程序的第一个 position 中没有显示我的 RecyclerView 时,我可以加载它。

I show you my UsersAdapter, maybe I missed a few things but everything seems correct to me我向您展示了我的 UsersAdapter,也许我错过了一些东西,但对我来说一切似乎都是正确的

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如果有人可以帮助我,我将不胜感激

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

try this尝试这个

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

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建议:您不需要将您的列表放入适配器的构造函数中, setUserList方法为您完成

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM