Android RecyclerView报错No adapter attached; skipping layout问题求助
问题排查与解决方案
核心错误定位
日志中前三条报错为系统/GPU相关的底层日志,和列表无法加载无关,核心问题是第四条错误:E/RecyclerView: No adapter attached; skipping layout
问题原因
- 你当前的代码逻辑是异步网络请求成功后才给RecyclerView设置Adapter和LayoutManager,网络请求是耗时操作,在请求返回前RecyclerView已经完成首次绘制,此时没有绑定Adapter就会触发该报错,跳过布局渲染。
- 如果后续出现网络请求失败、服务端返回的
obj.optString("selected")不等于selected的情况,setupRecycler()方法永远不会执行,RecyclerView永远不会绑定Adapter,列表自然无法展示内容。
修复方案
调整初始化逻辑,在onCreateView阶段就完成RecyclerView的基础配置,网络请求拿到数据后仅更新数据集即可:
第一步:修改ListPetientFragment逻辑
public class ListPetientFragment extends Fragment { private String URLstring = "http://192.168.43.29:8080/emedical/list.php"; // 提前初始化空数据集 private ArrayList<DataModel> dataModelArrayList = new ArrayList<>(); private RvAdapter rvAdapter; private RecyclerView recyclerView; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_list,container,false); recyclerView = v.findViewById(R.id.recycler); // 提前完成RecyclerView基础配置 initRecycler(); // 发起网络请求 fetchingJSON(); return v; } private void initRecycler(){ // 初始化Adapter传入空数据集 rvAdapter = new RvAdapter(getContext(),dataModelArrayList); recyclerView.setAdapter(rvAdapter); // 仅设置一次LayoutManager即可 recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); } private void fetchingJSON() { StringRequest stringRequest = new StringRequest(Request.Method.GET, URLstring, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d("strrrrr", ">>" + response); try { JSONObject obj = new JSONObject(response); if(obj.optString("selected").equals("selected")){ // 清空原有数据 dataModelArrayList.clear(); JSONArray dataArray = obj.getJSONArray("code1"); for (int i = 0; i < dataArray.length(); i++) { DataModel playerModel = new DataModel(); JSONObject dataobj = dataArray.getJSONObject(i); playerModel.setNames(dataobj.getString("names")); playerModel.setPhone(dataobj.getString("phoneNumber")); playerModel.setDisease(dataobj.getString("disease")); dataModelArrayList.add(playerModel); } // 通知Adapter数据更新即可 rvAdapter.notifyDataSetChanged(); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show(); } }); RequestQueue requestQueue = Volley.newRequestQueue(getActivity()); requestQueue.add(stringRequest); } }
第二步(可选优化):给RvAdapter添加更新数据集的方法
可以在RvAdapter里新增一个setData方法,避免直接操作外部的数据集,代码更规范:
// 在RvAdapter类中添加如下方法 public void setData(List<DataModel> newData){ this.dataList = newData; notifyDataSetChanged(); }
之后网络请求成功后直接调用rvAdapter.setData(dataModelArrayList);即可。
额外排查点
修改后如果还是没有数据,可以按顺序检查:
- 查看日志中
Log.d("strrrrr", ">>" + response);的输出,确认服务端是否正常返回了符合格式的数据 - 确认服务端返回的JSON中
selected字段的值是否为selected,code1字段是否为合法的数组格式
内容的提问来源于stack exchange,提问作者Meston Enock
相关产品推荐
相关产品推荐

