RecyclerView报错“No adapter attached; skipping layout”问题求助
解决RecyclerView "No adapter attached; skipping layout" 错误
尝试从网络接口获取评论数据展示到RecyclerView时,始终出现“No adapter attached; skipping layout”错误,已确认CommentAdapter类存在,但调试许久仍未解决问题,以下是相关代码及排查方案:
相关代码
RecyclerView布局XML
<androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_comments" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="?attr/actionBarSize" android:layout_marginBottom="?attr/actionBarSize"/>
CommentAdapter类
public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.CommentsHolder>{ private Context context; private ArrayList<Comment> list; public CommentAdapter(Context context, ArrayList<Comment> list) { this.context = context; this.list = list; } @NonNull @Override public CommentsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_comment, parent, false); return new CommentsHolder(v); } @Override public void onBindViewHolder(@NonNull CommentsHolder holder, int position) { Comment comment = list.get(position); Picasso.get().load(comment.getUser().getProfile_image_url()).into(holder.circleImageProfileComment); holder.nameComment.setText(comment.getUser().getName()); holder.dateComment.setText(comment.getDate()); holder.comment.setText(comment.getComment()); } @Override public int getItemCount() { return list.size(); } class CommentsHolder extends RecyclerView.ViewHolder{ private CircleImageView circleImageProfileComment; private TextView nameComment, dateComment, comment; private ImageButton imgBtnComment; public CommentsHolder(@NonNull View itemView) { super(itemView); circleImageProfileComment = itemView.findViewById(R.id.imgCommentProfile); nameComment = itemView.findViewById(R.id.commentName); dateComment = itemView.findViewById(R.id.commentDate); comment = itemView.findViewById(R.id.txtAllComments); imgBtnComment = itemView.findViewById(R.id.btnCommentOption); } } }
CommentActivity类
public class CommentActivity extends AppCompatActivity { private RecyclerView recyclerViewC; private ArrayList<Comment> list; private CommentAdapter adapter; private SharedPreferences sharedPreferences; private int postId = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_comment); init(); } private void init() { sharedPreferences = getApplication().getSharedPreferences("user", Context.MODE_PRIVATE); recyclerViewC = findViewById(R.id.recycler_comments); recyclerViewC.setHasFixedSize(true); recyclerViewC.setLayoutManager(new LinearLayoutManager(this)); postId = getIntent().getIntExtra("postId", 0); getComments(); } private void getComments() { list = new ArrayList<>(); String token = sharedPreferences.getString("token", ""); AndroidNetworking.post(Constant.COMMENTS) .addHeaders("Authorization", "Bearer "+token) .addBodyParameter("postId", postId+"") .setPriority(Priority.MEDIUM) .build() .getAsString(new StringRequestListener() { @Override public void onResponse(String response) { try { JSONObject object = new JSONObject(response); if (object.getBoolean("success")) { JSONArray comments = new JSONArray(object.getString("comments")); for (int i = 0; i < comments.length(); i++) { JSONObject comment = comments.getJSONObject(i); JSONObject user = comment.getJSONObject("user"); User mUser = new User(); mUser.setId(user.getInt("id")); mUser.setProfile_image_url(user.getString("profile_image_url")); mUser.setName(user.getString("name")); Comment mComment = new Comment(); mComment.setId(comment.getInt("id")); mComment.setUser(mUser); String dateTime = comment.getString("created_at"); mComment.setDate(dateTime.substring(0,10)+""+dateTime.substring(11,16)); mComment.setComment(comment.getString("comment")); list.add(mComment); } } adapter = new CommentAdapter(getApplicationContext(), list); recyclerViewC.setAdapter(adapter); } catch (JSONException e) { e.printStackTrace(); } } @Override public void onError(ANError anError) { } }); } }
问题原因及解决方案
核心原因
网络请求是异步操作,RecyclerView在Activity初始化完成、布局渲染时,网络请求还未返回数据,此时RecyclerView没有绑定任何Adapter,就会触发“No adapter attached; skipping layout”警告。
修复步骤
- 提前初始化Adapter并绑定到RecyclerView
在init方法中,先创建空的数据集和Adapter,立即绑定到RecyclerView,避免布局时无Adapter:
private void init() { sharedPreferences = getApplication().getSharedPreferences("user", Context.MODE_PRIVATE); recyclerViewC = findViewById(R.id.recycler_comments); recyclerViewC.setHasFixedSize(true); recyclerViewC.setLayoutManager(new LinearLayoutManager(this)); // 提前初始化空列表和Adapter list = new ArrayList<>(); adapter = new CommentAdapter(this, list); recyclerViewC.setAdapter(adapter); postId = getIntent().getIntExtra("postId", 0); getComments(); }
- 网络请求返回后更新数据并通知Adapter
在getComments的onResponse回调中,不再重新创建Adapter,而是清空旧数据、添加新数据,然后调用notifyDataSetChanged()通知RecyclerView刷新:
@Override public void onResponse(String response) { try { JSONObject object = new JSONObject(response); if (object.getBoolean("success")) { // 清空旧数据,避免重复添加 list.clear(); JSONArray comments = new JSONArray(object.getString("comments")); for (int i = 0; i < comments.length(); i++) { // 原有解析代码不变 list.add(mComment); } // 通知Adapter数据已更新 adapter.notifyDataSetChanged(); } } catch (JSONException e) { e.printStackTrace(); } }
优化Context使用
将getApplicationContext()改为CommentActivity.this(或直接this),Adapter使用Activity的Context更匹配生命周期,避免潜在内存泄漏问题。处理网络错误场景
在onError回调中添加日志或提示,方便排查请求失败情况:
@Override public void onError(ANError anError) { Log.e("CommentError", "请求失败: " + anError.getMessage()); Toast.makeText(CommentActivity.this, "加载评论失败", Toast.LENGTH_SHORT).show(); }
内容的提问来源于stack exchange,提问作者said hamisi
相关产品推荐
相关产品推荐

