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

Fragment中使用RecyclerView报错:No adapter attached skipping layout

解决RecyclerView在Fragment中不显示且报错"No adapter attached; skipping layout"的问题

我仔细看了你的代码和问题描述,虽然你已经排查了常见的Adapter初始化时机问题,但还有几个关键的细节错误导致了当前的问题,我帮你逐一梳理并给出修复方案:

问题1:DataBinding的错误使用

你在onCreateView里同时做了两件矛盾的事:用inflater.inflate加载布局,又调用DataBindingUtil.setContentView给Activity绑定布局——这完全是错误的用法!

DataBindingUtil.setContentView是给Activity初始化DataBinding用的,Fragment里必须用DataBindingUtil.inflate来加载布局,而且你返回的view和绑定的view不是同一个实例,导致后续onViewCreated里拿到的RecyclerView根本不是布局文件中定义的那个。

问题2:列表引用被替换,Adapter持有的还是旧空列表

在prepareWeightData方法里,你直接把mWeightData重新赋值为数据库查询的新List:

mWeightData = SQLite.select(). from(WeightData.class).queryList();

但你的Adapter在初始化时已经持有了原来空ArrayList的引用,新的List对象和Adapter里的mList没有任何关联,所以调用notifyDataSetChanged()根本不会生效——Adapter里的列表还是空的!

问题3:ListAdapter的getItemCount方法未完成

你的ListAdapter代码里,getItemCount()方法没有返回值,RecyclerView无法知道列表有多少项,自然不会渲染任何内容。


修复后的完整代码

1. 修正HistoryFragment代码

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.gosia.weightapplication.databinding.FragmentHistoryBinding;
import com.example.gosia.weightapplication.model.WeightData;
import com.orhanobut.logger.Logger;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import java.util.ArrayList;
import java.util.List;

public class HistoryFragment extends Fragment {
    private List<WeightData> mWeightData = new ArrayList<>();
    private FragmentHistoryBinding mFragmentHistoryBinding;
    private ListAdapter mAdapter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
        // 修正Fragment的DataBinding初始化方式
        mFragmentHistoryBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_history, viewGroup, false);
        mFragmentHistoryBinding.setVariable(this);
        // 返回绑定的根View
        return mFragmentHistoryBinding.getRoot();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 直接从Binding对象获取RecyclerView,无需findViewById
        RecyclerView recyclerView = mFragmentHistoryBinding.recyclerView;
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        // 初始化Adapter
        mAdapter = new ListAdapter(mWeightData, getContext());
        recyclerView.setAdapter(mAdapter);

        prepareWeightData();
    }

    private void prepareWeightData() {
        List<WeightData> newData = SQLite.select().from(WeightData.class).queryList();
        Logger.d(newData.toString());
        // 不要替换整个列表,清空旧数据后添加新数据,保持引用一致
        mWeightData.clear();
        mWeightData.addAll(newData);
        // 通知Adapter数据更新
        mAdapter.notifyDataSetChanged();
    }
}

2. 修正ListAdapter的getItemCount方法

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.gosia.weightapplication.model.WeightData;
import java.util.List;

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
    private List<WeightData> mList;
    private Context mContext;
    private final LayoutInflater mLayoutInflater;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView date, weight;
        public ImageView image;

        public ViewHolder(View v) {
            super(v);
            date = v.findViewById(R.id.text_view_date);
            weight = v.findViewById(R.id.text_view_weight);
            image = v.findViewById(R.id.image);
        }
    }

    public ListAdapter(List<WeightData> plist, Context pContext) {
        this.mList = plist;
        this.mContext = pContext;
        this.mLayoutInflater = LayoutInflater.from(this.mContext);
    }

    @Override
    public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = this.mLayoutInflater.inflate(R.layout.item_weight_history, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //set data
        WeightData weightData = mList.get(position);
        holder.date.setText(weightData.getLastDayWeightMeasurement());
        holder.weight.setText(weightData.getWeight());
    }

    // 补全getItemCount方法,返回列表实际长度
    @Override
    public int getItemCount() {
        return mList != null ? mList.size() : 0;
    }
}

额外提示

  • 以后在Fragment中使用DataBinding时,务必用DataBindingUtil.inflate初始化,并且返回getRoot()作为Fragment的View;
  • 更新列表数据时,尽量不要直接替换List对象,而是通过clear()+addAll()的方式保持引用一致,这样Adapter才能感知到数据变化;
  • 一定要确保Adapter的getItemCount()正确返回列表长度,否则RecyclerView无法渲染列表项。

内容的提问来源于stack exchange,提问作者Pefredo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:00:19