Android Studio中Kotlin实现Fragment用RecyclerView展示Firebase数据问题
问题描述
我有一个带导航栏和Fragment的Activity,在其中一个Fragment中向Firebase存储数据,希望在另一个Fragment中用RecyclerView展示这些数据。参照YouTube教程实现后,目标Fragment显示空白,附上相关代码寻求帮助。
相关代码
数据类
data class Event(var eventName: String, var eventTime:String?=null)
ViewModel
class EventViewModel :ViewModel() { private val repository : EventRepository private val _allEvents = MutableLiveData<List<Event>>() val allEvents : LiveData<List<Event>> = _allEvents init { repository= EventRepository().getInstance() repository.loadEvents(_allEvents) } }
Repository
class EventRepository { private val databaseReference: DatabaseReference= FirebaseDatabase.getInstance().getReference("PetEvents") @Volatile private var INSTANCE : EventRepository ?=null fun getInstance() : EventRepository{ return INSTANCE ?: synchronized(this) { val instance = EventRepository() INSTANCE=instance instance } } fun loadEvents(eventList : MutableLiveData<List<Event>>){ databaseReference.addValueEventListener(object:ValueEventListener{ override fun onDataChange(snapshot: DataSnapshot) { try { val _eventList : List<Event> = snapshot.children.map { dataSnapshot -> dataSnapshot.getValue(Event::class.java)!! } eventList.postValue(_eventList) } catch (e: Exception){ } } override fun onCancelled(error: DatabaseError) { TODO("Not yet implemented") } }) } }
Adapter
class EventAdapter : RecyclerView.Adapter<EventAdapter.MyViewHolder>() { private var eventList =ArrayList<Event>() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val itemView = LayoutInflater.from(parent.context).inflate( R.layout.event_item_cell, parent, false ) return MyViewHolder(itemView) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val currentItem = eventList[position] holder.eventName.text =currentItem.eventName holder.eventTime.text =currentItem.eventTime } override fun getItemCount(): Int { return eventList.size } fun updateEventList(eventList: List<Event>){ this.eventList.clear() this.eventList.addAll(eventList) notifyDataSetChanged() } class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){ val eventName :TextView = itemView.findViewById(R.id.txEventName) val eventTime :TextView = itemView.findViewById(R.id.txEventTime) } }
展示数据的Fragment
private lateinit var viewModel : EventViewModel private lateinit var eventRecyclerView: RecyclerView lateinit var adapter: EventAdapter class MainFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_main, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) eventRecyclerView=view.findViewById(R.id.recyclerView) eventRecyclerView.layoutManager= LinearLayoutManager(context) eventRecyclerView.setHasFixedSize(true) adapter = EventAdapter() eventRecyclerView.adapter= adapter viewModel = ViewModelProvider(this).get(EventViewModel::class.java) viewModel.allEvents.observe(viewLifecycleOwner, Observer { adapter.updateEventList(it) }) } }
备注:Fragment布局已添加RecyclerView,Item布局为CardView,不确定是否影响结果。
排查与修复步骤
添加错误日志定位问题
在Repository的onDataChange的catch块和onCancelled方法中添加日志打印,明确是数据读取失败还是解析出错:// onDataChange的catch块 catch (e: Exception){ Log.e("EventRepository", "数据解析失败", e) } // onCancelled方法实现 override fun onCancelled(error: DatabaseError) { Log.e("EventRepository", "数据库读取取消", error.toException()) }检查Firebase数据库规则
确保数据库规则允许读取操作,若未做用户认证,可临时调整规则为:{ "rules": { ".read": true, ".write": true } }注意:上线前需修改为符合安全要求的规则。
修复数据类序列化问题
Firebase解析数据需要无参构造函数,给Event类添加无参构造:data class Event(var eventName: String, var eventTime:String?=null){ constructor() : this("") }或者给
eventName设置默认值:data class Event(var eventName: String = "", var eventTime:String?=null)修正Repository单例实现
当前单例调用方式错误,ViewModel中初始化代码需改为:init { repository= EventRepository.getInstance() repository.loadEvents(_allEvents) }同时将Repository构造函数设为私有,避免外部直接实例化:
private constructor()验证RecyclerView及Item布局
- 确保
fragment_main中RecyclerView的宽高为match_parent,避免因布局尺寸问题导致内容不可见。 - 检查
event_item_cell中TextView的文字颜色与背景色有反差,且宽高设置合理。
- 确保
确认LiveData数据更新
在Fragment的Observer中添加日志,验证是否收到数据:viewModel.allEvents.observe(viewLifecycleOwner, Observer { Log.d("MainFragment", "收到数据条数:${it.size}") adapter.updateEventList(it) })
内容的提问来源于stack exchange,提问作者sueda
相关产品推荐
相关产品推荐

