Fragment中RecyclerView无法填充数据 同逻辑Activity正常运行问题求助
问题根因及修复方案
核心错误1:Fragment视图挂载逻辑错误
你在onCreate中初始化的Binding视图从未被挂载到Fragment上,所有RecyclerView的配置都作用在了无效视图上:
onCreate里inflate的FragmentTabHomeActivityBinding实例是局部变量,没有被持有onCreateView中重新inflate了完全无关的R.layout.cards_home布局返回,和你配置过RecyclerView的视图没有任何关联- 未给RecyclerView设置必填的
LayoutManager,RecyclerView没有布局规则不会渲染内容
核心错误2:Adapter逻辑错误
- ViewHolder的
bind方法中重复创建ViewHolder实例,没有使用当前绑定的itemView - 重复给同一个
R.id.cardHomeTitle赋值,name的值会被后续的superheroName覆盖 - 网络请求回包时直接用
!!取body,接口异常时会直接崩溃
修正后的代码
1. Fragment代码修正
class TabHomeActivity : Fragment() { // 全局持有binding实例 private var _binding: FragmentTabHomeActivityBinding? = null private val binding get() = _binding!! val itemList = ArrayList<HomeCards>() lateinit var adapter: HomeCardsAdapter override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? { // 这里返回binding的根视图 _binding = FragmentTabHomeActivityBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) adapter = HomeCardsAdapter() // 给RecyclerView设置LayoutManager,必填项 binding.rvHomeCards.layoutManager = LinearLayoutManager(requireContext()) binding.rvHomeCards.adapter = adapter loadData() } private fun loadData() { ApiManager.getInstance().service.listHeroes() .enqueue(object : Callback<ResponseData<List<HomeCards>>> { override fun onResponse( call: Call<ResponseData<List<HomeCards>>>, response: Response<ResponseData<List<HomeCards>>> ) { // 加判空避免崩溃 response.body()?.data?.let { listData -> itemList.clear() itemList.addAll(listData) adapter.updateData(itemList) } } override fun onFailure(call: Call<ResponseData<List<HomeCards>>>, t: Throwable) { // 建议加异常打印,方便排查问题 t.printStackTrace() } }) } // Fragment销毁时清空binding引用避免内存泄漏 override fun onDestroyView() { super.onDestroyView() _binding = null } }
2. Adapter代码修正
class HomeCardsAdapter() : RecyclerView.Adapter<HomeCardsAdapter.ViewHolder>() { // 初始化时给个默认空列表,避免lateinit的额外判空逻辑 private var itemList: List<HomeCards> = emptyList() lateinit var context: Context override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { context = parent.context val view = LayoutInflater.from(context).inflate(R.layout.cards_home, parent, false) return ViewHolder(view) } override fun getItemCount(): Int = itemList.size override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bind(itemList[position]) } fun updateData(list: List<HomeCards>) { itemList = list notifyDataSetChanged() } inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { // 提前初始化控件,避免每次bind都重复findViewById private val titleTv = itemView.findViewById<TextView>(R.id.cardHomeTitle) private val iconIv = itemView.findViewById<ImageView>(R.id.cardHomeIcon) fun bind(item: HomeCards) { // 不要重复创建ViewHolder,直接用当前实例的控件 titleTv.text = "${item.name}(${item.superheroName})" Glide.with(context) .load(item.photo) .diskCacheStrategy(DiskCacheStrategy.ALL) .circleCrop() .into(iconIv) } } }
内容的提问来源于stack exchange,提问作者Steve Rauco
相关产品推荐
相关产品推荐

