从Activity迁移至Fragment后RecyclerView报无适配器绑定错误
基于GeeksforGeeks的《Build a Movie App using Retrofit and MVVM Architecture with Kotlin》教程,用Kotlin开发面试练习用的简易电影应用,将原本在MainActivity的onCreate中的功能迁移至Fragment后,出现「E/RecyclerView: No adapter attached; skipping layout」错误。Adapter中的onCreateViewHolder和onBindViewHolder方法未触发日志,其余日志均正常输出,此前还遇到过DataBinding和SafeArgs相关错误。
核心问题分析
1. Fragment的View绑定错误
在onCreateView方法中,你先通过DataBindingUtil.inflate初始化了binding,但最后返回的是inflater.inflate(R.layout.fragment_movie_list, container, false)创建的全新View,导致binding关联的View从未被添加到界面中。后续在prepareRecyclerView中给binding.rvMovies设置适配器,实际是给一个未显示的RecyclerView设置,而界面上真正显示的RecyclerView没有任何适配器,因此出现错误。
2. Adapter中的日志位置错误
onCreateViewHolder中的Log.d(TAG, "onCreateViewHolder called")写在return语句之后,永远不会被执行,这也是你看不到该日志的原因之一。
修复方案
修复Fragment的onCreateView方法
将返回值改为binding.root,确保绑定的View是实际显示的View:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { Log.d(TAG,"onCreateView: called") binding = DataBindingUtil.inflate( inflater, R.layout.fragment_movie_list, container, false ) // 返回binding.root而不是重新inflate的View return binding.root }
调整Adapter中的日志位置
将onCreateViewHolder中的日志移到return之前:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { Log.d(TAG, "onCreateViewHolder called") // 移到return前 return ViewHolder( MovieLayoutBinding.inflate( LayoutInflater.from(parent.context) ) ) }
可选优化:初始化Adapter时设置空列表
为了避免初始状态下RecyclerView无数据的警告,可以在Adapter初始化时设置空列表,或者在ViewModel中给movieLiveData设置初始值:
// 在MovieAdapter的构造方法中初始化空列表 class MovieAdapter : RecyclerView.Adapter<MovieAdapter.ViewHolder>() { private var movieList = ArrayList<Result>() // 或者直接在构造方法中初始化 init { movieList = arrayListOf() } // ... 其他代码 }
验证修复
修复后,prepareRecyclerView中设置的适配器会关联到界面上实际显示的RecyclerView,当LiveData数据更新时,Adapter的setMovieList会触发notifyDataSetChanged,进而调用onCreateViewHolder和onBindViewHolder方法,日志会正常输出,RecyclerView也会显示数据。
内容的提问来源于stack exchange,提问作者MallSoft95

