我遇到过这样的情况:一个布局上有 3 个 RecyclerView。他们以某种方式相互依赖。数据来自房间数据库。
问题原型(问题陈述):假设您有类似(Floor1、Floor2、Floor3 等)的楼层,并且每个楼层内都有类似(Room1、Room2、Room3 等)的房间,并且每个房间内都有姓名类似(PersonA、PersonB、PersonC)的人。
给定的约束是:一个人不能在同一类型的两个不同房间中。
Edit 1:楼层、房间和人员以字符串列表的形式来自数据库。
您将如何使用(回收器视图)或单个屏幕布局上的任何内容来显示这一点。楼层、房间和人员的数量可以是无限的。但该信息是从房间数据库中获取的。
我的方法:(这不是一个完整的方法),但我想在顶部有一个 RecyclerView 来容纳一定数量的楼层。我们使用查询从数据库中获取总楼层并对它们进行排序并显示。在此期间onBindViewHolder()
在楼层适配器中,我们有一个条件,检查是否有与该楼层关联的房间,如果有,则我们进行另一个查询以从数据库中获取并显示它(可能使用新的回收器视图),但我不知道怎么做。嵌套回收器视图是可以在这里使用的东西吗?
它并没有就此停止,因为我们使用该房间名称对数据库进行另一个查询以查找该房间内的所有人员。这是回收者的另一个观点。
我正在考虑应用这种方法,但我觉得实施这种方法有很多阻碍。我不确定这是否是处理此类事情的方法。
Image for reference :
我正在寻找任何信息,如果您遇到过此类情况,那么您采取了什么方法。是否有任何库可用于简化此任务,或者您可以提供的任何知识都会有所帮助。谢谢!
Edit 2:现在正在做什么:
我尝试实现嵌套回收器视图。事情似乎工作正常,因为现在我有两个适配器(用于地板和房间),我正在从片段中充气地板适配器,并从片段中充气房间适配器onBindViewHolder
地板适配器。
我现在面临的问题是,在回收器视图内,我正确地获取了楼层列表,但对于房间列表(在子回收器视图中),我只获取了最后一层的列表。
Check this image for reference (Floor 2 and 1 also have rooms but I am only getting room C1 which is present in last floor which is 3) :
适配器中的当前代码:
class FloorsAdapter(
private val controlPanelViewModel: ControlPanelViewModel,
private val activity: FragmentActivity?
) : RecyclerView.Adapter<FloorsAdapter.FloorViewHolder>() {
private var floorList = emptyList<String>()
private lateinit var roomAdapter: RoomAdapter
inner class FloorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): FloorViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ListItemControlPanelFloorsBinding.inflate(layoutInflater, parent, false)
return FloorViewHolder(binding.root)
}
override fun onBindViewHolder(holder: FloorsAdapter.FloorViewHolder, position: Int) {
val item = floorList[position]
ListItemControlPanelFloorsBinding.bind(holder.itemView).apply {
Timber.d("Current floor is $item, Floor List is : $floorList")
tvFloor.text = item
roomAdapter = RoomAdapter(controlPanelViewModel, activity)
rvRoomControlPanel.adapter = roomAdapter
rvRoomControlPanel.layoutManager = LinearLayoutManager(activity)
controlPanelViewModel.getAllRooms(item).observeForever(Observer {
Timber.d("List of rooms : $it")
//Finding distinct rooms
val distinct = it.toSet().toList()
Timber.d("Distinct rooms list : $distinct")
roomAdapter.roomList(distinct)
})
}
}
@SuppressLint("NotifyDataSetChanged")
fun floorList(floors: List<String>) {
this.floorList = floors
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return floorList.size
}
}
class RoomAdapter(
private val controlPanelViewModel: ControlPanelViewModel,
private val activity: FragmentActivity?
) : RecyclerView.Adapter<RoomAdapter.RoomViewHolder>() {
private var roomList = emptyList<String>()
inner class RoomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RoomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ListItemControlPanelRoomsBinding.inflate(layoutInflater, parent, false)
return RoomViewHolder(binding.root)
}
override fun onBindViewHolder(holder: RoomViewHolder, position: Int) {
val item = roomList[position]
ListItemControlPanelRoomsBinding.bind(holder.itemView).apply {
Timber.d("Current room is $item")
tvRoom.text = item
}
}
@SuppressLint("NotifyDataSetChanged")
fun roomList(room: List<String>) {
this.roomList = room
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return roomList.size
}
}
片段中用于充气地板适配器的代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.rvFloors.adapter = adapter
binding.rvFloors.layoutManager = LinearLayoutManager(requireContext())
controlPanelViewModel.getAllFloors.observe(viewLifecycleOwner, Observer{
Timber.d("List is $it")
//Remove duplicates from received list
val distinct = it.toSet().toList()
Timber.d("List after removing duplicates: $distinct")
adapter.floorList(distinct)
})
Timber.d("Adapter: $adapter" )
}
Edit 3:通过查看日志,我发现了一些可以解释为什么会发生这种情况的内容。因此,楼层列表首先被执行
controlPanelViewModel.getAllFloors.observe(viewLifecycleOwner, Observer{
Timber.d("List is $it")
//Remove duplicates from received list
val distinct = it.toSet().toList()
Timber.d("List after removing duplicates: $distinct")
adapter.floorList(distinct)
})
当我们正在膨胀房间回收者从地板适配器的视图时
roomAdapter = RoomAdapter(controlPanelViewModel, activity)
rvRoomControlPanel.adapter = roomAdapter
rvRoomControlPanel.layoutManager = LinearLayoutManager(activity)
controlPanelViewModel.getAllRooms(item).observeForever(Observer {
Timber.d("List of rooms : $it")
//Finding distinct rooms
val distinct = it.toSet().toList()
Timber.d("Distinct rooms list : $distinct")
roomAdapter.roomList(distinct)
})
当从 Room 获取数据时,会有一点延迟。所以不要做类似的事情(Floor 1 -> Room1, Room2
我们得到类似的东西(Floor1, Floor2 -> Room3, Room4)
。有关先前楼层房间的数据正在丢失。
在这里做什么?除非我们已获取所有房间并使用文本视图显示,否则如何停止下一层的执行。