【发布时间】:2019-05-24 19:48:45
【问题描述】:
我正在尝试检索一个项目列表,其中每个项目还可以包含 Room 数据库中的子项目(树结构)。我想在 RecyclerView 中使用这些项目,这取决于项目是否有子项目本身会产生另一个 RecyclerView 来包含这些子项目。我遇到的问题是如何正确地将这些项目检索为 LiveData。在数据库中,每个项目都有一个 parent_id 指向项目的父项。
@Entity(
tableName = "items_table",
foreignKeys = [ForeignKey(entity = Item::class,
parentColumns = ["id"],
childColumns = ["parent_id"],
onDelete = ForeignKey.CASCADE)])
data class Item(
@PrimaryKey(autoGenerate = true)
var id: Int,
var parent_id: Int?,
var name: String
... // Additional fields
)
我现在使用“getRoot”和“getChildren”通过 DAO 检索项目:
@Dao
interface ItemsDao{
@Query("SELECT * FROM items_table WHERE parent_id=:parent_id")
fun findChildItems(parent_id: Int): LiveData<List<Item>>
@Transaction
@Query("SELECT * FROM items_table WHERE parent_id IS NULL")
fun getRoot(): LiveData<Item>
}
现在应该使用 RecyclerView 的适配器来使用项目和子项目
class ItemListAdapter(...) : RecyclerViewAdapter<ItemViewHolder> {
override fun getItemViewType(someItem): Int {
return when someItem.hasChildren {
true -> 0
false -> 1
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder{
val layoutInflater = LayoutInflater.from(parent.context)
when (viewType) {
0 -> { // Item has children
val inflated = // inflated with new recyclerView
return ItemViewHolder(inflated, 0)
}
else -> { // Item has no children
val inflated = // layout without new recyclerView
return itemViewHolder(inflated, 1)
}
}
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int)
// [...]
when (holder.type) {
0 -> {
// Customize the view
holder.itemView.recyclerView.adapter = ItemListAdapter(..., context)
}
else -> {
// Customize the view
}
}
}
}
由于我的数据库是使用 ViewModel 访问的,而 Adapter 无法访问 ViewModel,我将如何使用包含相应子项的 LiveData 来提供包含子项及其各自子项等的项?我应该将 Dao 还是 viewModel 传递给适配器。在那种情况下,我如何从适配器内观察 LiveData,因为它不是片段/活动?有没有更好的解决方案?
【问题讨论】:
标签: android kotlin android-recyclerview tree android-room