Android RecyclerView报错No adapter attached; skipping layout求助
解决RecyclerView "No adapter attached; skipping layout" 报错问题
嘿,我注意到你在开发Android应用时遇到了RecyclerView的适配问题——在BlueStacks模拟器上运行正常,但在其他设备测试时出现RecyclerView No adapter attached; skipping layout的报错。咱们来一步步拆解问题并修复它:
问题根源分析
你的代码里有两个关键问题:
- Adapter绑定时机依赖数据库数据:只有当数据库查询的Cursor有数据时,才会给RecyclerView设置Adapter。如果Cursor为空(比如其他设备上数据库还没数据,或者查询结果为空),循环根本不会执行,RecyclerView就一直没有绑定Adapter,直接触发报错。而BlueStacks上数据库有数据,循环正常执行,Adapter被绑定所以没报错。
- 循环内重复创建Adapter:你在
while (res.moveToNext())循环里每次都新建Adapter并设置给RecyclerView,这是没必要的性能浪费,完全可以只创建一次Adapter,数据更新时通知它即可。
修复后的代码
修改后的Fragment代码
public class AsosiyFragment extends Fragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.form_asosiy, container, false); return rootView; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); DBAdapter mDBAdapter = new DBAdapter(getContext()); Spinner spinner_viloyatlar = view.findViewById(R.id.spinner_viloyatlar); RecyclerView recyclerView = view.findViewById(R.id.roza_vaqtlari); recyclerView.setHasFixedSize(true); Context context = view.getContext(); LinearLayoutManager layoutManager = new LinearLayoutManager(context); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); // 1. 提前初始化数据列表和Adapter,直接绑定给RecyclerView List<RamazonAdapter> ramazonAdapters = new ArrayList<>(); Adapter adapter1 = new Adapter(getActivity(), ramazonAdapters); recyclerView.setAdapter(adapter1); String[] VILOYAT_NOMI_KIRIL = { "Андижон","Бухоро", "Жиззах","Қашқадарё", "Қорақалпоғистон","Навоий", "Наманган","Самарқанд", "Сурхондарё","Сирдарё", "Тошкент","Фарғона", "Хоразм" }; // Add viloyatlar to spinner ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i <= 12; i++){ list.add(VILOYAT_NOMI_KIRIL[i]); } ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),R.layout.spinner_item,R.id.item,list); spinner_viloyatlar.setAdapter(adapter); // get all data from sqlite Cursor res = mDBAdapter.getAllData(); // 清空旧数据 ramazonAdapters.clear(); // 安全遍历Cursor if (res != null && res.moveToFirst()) { do { String data1 = res.getString(1); String data2 = res.getString(2); String data3 = res.getString(3); String data4 = res.getString(4); RamazonAdapter rAdapter = new RamazonAdapter(data1,data2,data3,data4); ramazonAdapters.add(rAdapter); } while (res.moveToNext()); // 2. 数据加载完成后,统一通知Adapter更新 adapter1.notifyDataSetChanged(); // 关闭Cursor,避免内存泄漏 res.close(); } } }
可选:优化Adapter的空列表处理
为了更友好地应对空数据场景,可以给Adapter加个小优化:
@Override public int getItemCount() { // 避免列表为空时的潜在空指针问题 return ramazonAdapterList == null ? 0 : ramazonAdapterList.size(); }
修复说明
- 提前绑定Adapter:不管数据库有没有数据,初始化阶段就给RecyclerView设置Adapter,这样RecyclerView在布局时就不会因为缺少Adapter而报错。
- 优化数据更新逻辑:只创建一次Adapter,数据加载完成后调用
notifyDataSetChanged()通知UI更新,避免重复创建Adapter的性能损耗。 - 安全处理Cursor:添加Cursor有效性判断,使用
do-while循环遍历数据,并且记得关闭Cursor,防止内存泄漏。
这样修改后,无论数据库是否有数据,RecyclerView都能正常绑定Adapter,不会再出现No adapter attached的报错,同时代码结构也更合理。
内容的提问来源于stack exchange,提问作者Muhammed
相关产品推荐
相关产品推荐

