You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

错误分析

  1. RecyclerView初始化时机滞后:仅在网络请求回调中设置布局管理器和适配器,导致页面加载初期RecyclerView无绑定适配器,触发No adapter attached警告。
  2. 循环重复操作冗余:在for循环中重复创建Adapter和LayoutManager并绑定,完全没必要,既浪费资源也可能干扰数据绑定逻辑。
  3. 数据映射可能不匹配: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:05:33