RecyclerView报错‘No adapter attached; skipping layout’的原因与解决
这个警告是Android开发中RecyclerView的常见问题,本质是RecyclerView完成首次布局绘制时,还没有绑定有效的Adapter实例,系统就会跳过布局流程——哪怕你后续补上Adapter,这个初始化阶段的警告还是会弹出来。结合你贴的代码,我帮你分析下原因和解决办法:
错误根源
Adapter可能被初始化为null
你用context?.let{ UserAdapter(it,mUser as ArrayList<User>,true) }创建Adapter,这里的问题是:如果Fragment还没完全依附到Activity(比如onCreateView执行时context临时为空),let代码块不会执行,导致userAdapter是null,这时候recyclerView?.adapter=userAdapter相当于没给RecyclerView绑定任何Adapter,直接触发警告。RecyclerView初始visibility不影响警告
你给RecyclerView设置了android:visibility="gone",但哪怕控件不可见,系统依然会在布局阶段检查Adapter是否存在,所以这个属性不是问题所在。
具体解决办法
1. 确保Adapter一定被创建(推荐)
Fragment中可以用requireContext()替代context,它会返回非空的Context(如果Context为空会直接抛出异常,帮你提前发现问题),修改代码如下:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_search, container, false) recyclerView = view.findViewById(R.id.recycler_view_search) recyclerView?.setHasFixedSize(true) recyclerView?.layoutManager = LinearLayoutManager(context) mUser = ArrayList() // 用requireContext()保证Context非空,Adapter一定被初始化 userAdapter = UserAdapter(requireContext(), mUser as ArrayList<User>, true) recyclerView?.adapter = userAdapter view.search_edit_text.addTextChangedListener(object: TextWatcher{ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { TODO("Not yet implemented") } // 记得补全TextWatcher的另外两个方法哦 override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { TODO("Not yet implemented") } override fun afterTextChanged(s: Editable?) { TODO("Not yet implemented") } }) return view }
2. 提前绑定空数据Adapter(适合异步加载场景)
如果你的数据是异步获取的,可以先给RecyclerView绑定一个空数据的Adapter,后续数据加载完成后再更新Adapter的数据:
// 初始化阶段先绑定空Adapter mUser = ArrayList() userAdapter = UserAdapter(requireContext(), mUser, true) recyclerView?.adapter = userAdapter // 异步获取数据后更新 fun onDataLoaded(newUsers: List<User>) { mUser.clear() mUser.addAll(newUsers) userAdapter.notifyDataSetChanged() }
3. 用链式调用避免空指针(可选优化)
可以用apply函数简化RecyclerView的初始化代码,避免多次判断recyclerView是否为null:
view.findViewById<RecyclerView>(R.id.recycler_view_search).apply { setHasFixedSize(true) layoutManager = LinearLayoutManager(context) adapter = UserAdapter(requireContext(), mUser as ArrayList<User>, true) }
按照上面的方法修改后,这个警告应该就会消失了。
内容的提问来源于stack exchange,提问作者Akib Algohar

