Android获取Firebase数据闪退 报findViewById(R.id.tv_percent)不可为空
问题根因
崩溃触发点非常明确:SensorAdapter创建列表条目时加载了错误的布局文件,导致findViewById找不到目标控件返回null,在Kotlin非空类型检查下直接抛出空指针。
你当前适配器的onCreateViewHolder代码:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.fragment_iot, parent, false) return ViewHolder(itemView) }
这里加载的R.layout.fragment_iot是IOTFragment本身的根布局,这个布局里只放了RecyclerView控件,根本不存在id为tv_percent、tittle_parameter的两个TextView,自然查找结果为null。
修复方案
- 先确认你为RecyclerView列表子项单独创建的布局文件(通常命名类似
item_sensor.xml),核对该布局内确实包含两个TextView,id分别为tv_percent、tittle_parameter,注意拼写:你代码里写的tittle是拼写错误(正确拼写为title),如果布局文件里用了正确拼写的id,也会触发同样的找不到控件问题。 - 修改
onCreateViewHolder的布局加载逻辑,替换为正确的子项布局资源ID:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { // 将R.layout.fragment_iot替换为你实际的列表子项布局ID val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_sensor, parent, false) return ViewHolder(itemView) }
可选优化项
你当前的Firebase数据回调逻辑存在性能问题:每次数据变化都会重新创建Adapter实例,会导致列表滑动状态丢失、重复绑定开销,建议调整:
- 将Adapter设为IOTFragment的全局成员变量
private lateinit var mAdapter: SensorAdapter
- 在
onViewCreated初始化RecyclerView时就完成Adapter绑定,不要等到数据返回再创建
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sensorRecyclerView = binding.sensorView sensorRecyclerView.layoutManager = LinearLayoutManager(requireActivity()) sensorRecyclerView.setHasFixedSize(true) sensorList = arrayListOf() mAdapter = SensorAdapter(sensorList) sensorRecyclerView.adapter = mAdapter getSensorData() }
- 数据回调中更新完列表后直接调用刷新方法,不要重复实例化Adapter,同时去掉
!!强转避免异常数据触发崩溃
override fun onDataChange(snapshot: DataSnapshot) { sensorList.clear() if (snapshot.exists()){ for (sensorSnap in snapshot.children){ val sensorData = sensorSnap.getValue(Sensor::class.java) sensorData?.let { sensorList.add(it) } } mAdapter.notifyDataSetChanged() } }
内容的提问来源于stack exchange,提问作者micinable
相关产品推荐
相关产品推荐

