RecyclerView Adapter未初始化导致SearchView点击崩溃问题求助
问题原因
你遇到的kotlin.UninitializedPropertyAccessException是因为两点:
- 声明的
lateinit var adapter从未被赋值,你在getData方法里仅创建Adapter并直接绑定到RecyclerView,但未将实例赋值给全局adapter变量; - Firebase数据加载是异步操作,用户可能在数据未加载完成时就触发SearchView查询,此时全局
adapter仍未初始化,调用adapter.searcDataList就会崩溃。
解决方案
步骤1:提前初始化Adapter
在设置RecyclerView布局管理器后,先创建空数据的Adapter,赋值给全局变量并绑定到RecyclerView,避免异步加载期间adapter未初始化的问题。
步骤2:在Firebase回调中更新Adapter数据
不再重新创建Adapter实例,直接调用Adapter的searcDataList方法更新数据,保证全局adapter变量始终指向同一个实例。
修改后的GlosaryFragment代码
class GlosaryFragment : Fragment() { private lateinit var preferences: Preferences private lateinit var mDatabase: DatabaseReference private var datalist = ArrayList<Istilah>() private lateinit var adapter: DaftarIstilahAdapter private var _binding: FragmentGlosaryBinding? = null private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = FragmentGlosaryBinding.inflate(inflater, container, false) return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) preferences = Preferences(requireActivity().applicationContext) mDatabase = FirebaseDatabase.getInstance().getReference("Istilah") binding.tvName.text = preferences.getValues("nama") binding.tvSchool.text = preferences.getValues("sekolah") Glide.with(this) .load(preferences.getValues("url")) .apply(RequestOptions.circleCropTransform()) .into(binding.ivAvatar) // 提前初始化Adapter并绑定到RecyclerView binding.rvDaftarIstilah.layoutManager = LinearLayoutManager(context) adapter = DaftarIstilahAdapter(datalist) { val intent = Intent(context, DetailActivity::class.java).putExtra("data", it) startActivity(intent) } binding.rvDaftarIstilah.adapter = adapter getData() binding.searchView.setOnQueryTextListener(object : androidx.appcompat.widget.SearchView.OnQueryTextListener{ override fun onQueryTextSubmit(query: String?): Boolean { return false } override fun onQueryTextChange(newText: String): Boolean { searchList(newText) return true } }) } fun searchList(text: String){ val searchList = kotlin.collections.ArrayList<Istilah>() for (dataclass in datalist){ // 增加空安全判断,避免空指针 if (dataclass.istilah?.lowercase()?.contains(text.lowercase()) == true){ searchList.add(dataclass) } } adapter.searcDataList(searchList) } private fun getData() { mDatabase.addValueEventListener(object : ValueEventListener { override fun onDataChange(snapshot: DataSnapshot) { datalist.clear() for (getSnapshot in snapshot.children) { val istilah = getSnapshot.getValue(Istilah::class.java) // 安全添加数据,避免强制非空崩溃 istilah?.let { datalist.add(it) } } // 直接更新Adapter数据,不再重新创建实例 adapter.searcDataList(datalist) } override fun onCancelled(error: DatabaseError) { Toast.makeText(context, "" + error.message, Toast.LENGTH_LONG).show() } }) } override fun onDestroyView() { super.onDestroyView() _binding = null } }
额外优化说明
- 在
searchList和getData中添加了空安全判断,替换了原代码中的强制非空!!,避免潜在的空指针崩溃; - 统一使用同一个Adapter实例,保证数据更新和搜索功能的一致性。
内容的提问来源于stack exchange,提问作者Rahmatul Ulya
相关产品推荐
相关产品推荐

