RecyclerView布局数量正常但文本为空,伴未绑定适配器错误
问题描述
开发疫苗名称列表功能时,从数据库获取数据后,RecyclerView生成了对应数组长度(6个)的空白布局,疫苗名称未显示,同时Logcat提示No adapter attached; skipping layout错误。
相关代码
AboutVaccines.java
private void viewJsonData() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(BaseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); myApi = retrofit.create(MyAPI.class); Call<ArrayList<VaccineModel>> modelarraylist = myApi.callArrayList(); modelarraylist.enqueue(new Callback<ArrayList<VaccineModel>>() { @Override public void onResponse(Call<ArrayList<VaccineModel>> call, retrofit2.Response<ArrayList<VaccineModel>> response) { modelArrayList = response.body(); int i = 0; for(i = 0; i < modelArrayList.size(); i++){ vaccineAdapter = new VaccineAdapter(modelArrayList, AboutVaccines.this); LinearLayoutManager manager = new LinearLayoutManager(AboutVaccines.this, RecyclerView.VERTICAL, false); vaccinerecycler.setLayoutManager(manager); vaccinerecycler.setAdapter(vaccineAdapter); } } @Override public void onFailure(Call<ArrayList<VaccineModel>> call, Throwable t) { Toast.makeText(AboutVaccines.this, "data was not fetched!", Toast.LENGTH_SHORT).show(); } }); }
VaccineAdapter.java
public class VaccineAdapter extends RecyclerView.Adapter<VaccineAdapter.ViewHolder> { private ArrayList<VaccineModel> modelArrayList; private Context context; public VaccineAdapter(ArrayList<VaccineModel> modelArrayList, Context context) { this.modelArrayList = modelArrayList; this.context = context; } @NonNull @Override public VaccineAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.abtvaccinesrecyclerview, parent, false); return new VaccineAdapter.ViewHolder(view); } @Override public void onBindViewHolder(@NonNull VaccineAdapter.ViewHolder holder, int position) { holder.vname.setText(modelArrayList.get(position).getVaccineName()); } @Override public int getItemCount() { return modelArrayList.size(); } public class ViewHolder extends RecyclerView.ViewHolder { TextView vname; public ViewHolder(@NonNull View itemView) { super(itemView); vname = itemView.findViewById(R.id.vaccinename); } } }
MyAPI.java
public interface MyAPI { @GET("vaccinedata.php") Call<ArrayList<VaccineModel>> callArrayList(); }
错误分析
- RecyclerView初始化时机滞后:仅在网络请求回调中设置布局管理器和适配器,导致页面加载初期RecyclerView无绑定适配器,触发
No adapter attached警告。 - 循环重复操作冗余:在
for循环中重复创建Adapter和LayoutManager并绑定,完全没必要,既浪费资源也可能干扰数据绑定逻辑。 - 数据映射可能不匹配:
VaccineModel的getVaccineName()是否正确对应接口返回的JSON字段,需确认字段名是否一致或是否使用@SerializedName处理不匹配情况。
修复方案
1. 提前初始化RecyclerView
在Activity的onCreate方法中先设置布局管理器和空适配器,避免加载警告:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); vaccinerecycler = findViewById(R.id.your_recycler_id); // 提前设置布局管理器 LinearLayoutManager manager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false); vaccinerecycler.setLayoutManager(manager); // 绑定空适配器 vaccineAdapter = new VaccineAdapter(new ArrayList<>(), this); vaccinerecycler.setAdapter(vaccineAdapter); viewJsonData(); // 发起网络请求 }
2. 修正网络请求回调逻辑
移除循环,仅在数据返回后更新适配器:
private void viewJsonData() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(BaseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); myApi = retrofit.create(MyAPI.class); Call<ArrayList<VaccineModel>> modelarraylist = myApi.callArrayList(); modelarraylist.enqueue(new Callback<ArrayList<VaccineModel>>() { @Override public void onResponse(Call<ArrayList<VaccineModel>> call, retrofit2.Response<ArrayList<VaccineModel>> response) { if (response.isSuccessful() && response.body() != null) { modelArrayList = response.body(); // 更新适配器数据 vaccineAdapter.setData(modelArrayList); vaccineAdapter.notifyDataSetChanged(); // 或者直接重新设置适配器: // vaccineAdapter = new VaccineAdapter(modelArrayList, AboutVaccines.this); // vaccinerecycler.setAdapter(vaccineAdapter); } } @Override public void onFailure(Call<ArrayList<VaccineModel>> call, Throwable t) { Toast.makeText(AboutVaccines.this, "数据获取失败!", Toast.LENGTH_SHORT).show(); } }); }
3. 优化适配器(添加数据更新方法)
给适配器增加数据更新方法,避免重复创建适配器对象:
public class VaccineAdapter extends RecyclerView.Adapter<VaccineAdapter.ViewHolder> { private ArrayList<VaccineModel> modelArrayList; private Context context; public VaccineAdapter(ArrayList<VaccineModel> modelArrayList, Context context) { this.modelArrayList = modelArrayList; this.context = context; } // 添加数据更新方法 public void setData(ArrayList<VaccineModel> newData) { this.modelArrayList = newData; notifyDataSetChanged(); } @NonNull @Override public VaccineAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.abtvaccinesrecyclerview, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull VaccineAdapter.ViewHolder holder, int position) { VaccineModel model = modelArrayList.get(position); // 增加空值判断,避免空指针 holder.vname.setText(model.getVaccineName() != null ? model.getVaccineName() : ""); } @Override public int getItemCount() { return modelArrayList != null ? modelArrayList.size() : 0; } public class ViewHolder extends RecyclerView.ViewHolder { TextView vname; public ViewHolder(@NonNull View itemView) { super(itemView); vname = itemView.findViewById(R.id.vaccinename); } } }
4. 检查VaccineModel字段映射
确保Model类字段与接口返回JSON字段匹配,若字段名不一致,使用@SerializedName注解:
public class VaccineModel { // 示例:若JSON返回字段为"vaccine_name",则添加注解 @SerializedName("vaccine_name") private String vaccineName; public String getVaccineName() { return vaccineName; } public void setVaccineName(String vaccineName) { this.vaccineName = vaccineName; } }
内容的提问来源于stack exchange,提问作者eri
相关产品推荐
相关产品推荐

