在 MVVM+Repository+LiveData 设置中获取 HashMap<Model1, List<Model2>>?
Get HashMap<Model1, List<Model2>> in an MVVM+Repostiory+LiveData setting?
所以我正在开发这个愚蠢的小应用程序来练习 MVVM 和存储库模式。我现在有两个模型 类。它们是 Category
和 SubCategory
,我为其定义了以下数据 类:
@Entity(tableName = "categories")
data class Category(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int,
@ColumnInfo(name = "name")
val name: String
) {
}
和
/**
* One to many Relationship from Category to SubCategory
*/
@Entity(
tableName = "sub_categories", foreignKeys = arrayOf(
ForeignKey(
entity = Category::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("category_id")
)
)
)
data class SubCategory(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int,
@ColumnInfo(name = "name")
val name: String,
@ColumnInfo(name = "category_id")
val categoryId: Int
) {
}
如您所见,我对资源进行了建模,因此我们需要传递 categoryId 以获取与类别相关的子类别。
现在我对这个 MVVM 和 LiveData 以及存储库模式还很陌生。
我的问题是我正在使用 ExpandableListView
来填充类别下的子类别,而 Adapter
需要 HashMap<Category, List<SubCategory>
才能显示可扩展的列表视图。
所以我的问题是如何使用 db->dao->repository->viewmodel
的方法从我的数据库中获取 HashMap<Category, List<SubCategory>
以及 adpater
的位置。
我想创建一个像 CategorySubCategoryRespository
这样的单独的存储库,这样我就可以执行以下操作不会有帮助吗?:
class CategorySubCategoryRepository(
private val categoryDao: CategoryDao,
private val subCategoryDao: SubCategoryDao
) {
val allCategoriesSubCategories: LiveData<HashMap<Category, List<SubCategory>>>
get() {
val hashMap: HashMap<Category, List<SubCategory>> = hashMapOf()
for (category in categoryDao.getList()) {
hashMap[category] = subCategoryDao.getSubCategoriesListForCategory(category.id)
}
return hashMap
}
}
}
PS:我想尽可能使用LiveData
所以我最终做的是,在我的 CategorySubcategoryRepository
中,我从 CategoryDao
和 SubcategoryDao
构建了 Hashmap,如下所示:
class CategorySubCategoryRepository(
private val categoryDao: CategoryDao,
private val subCategoryDao: SubCategoryDao
) {
fun getHashMap(): LiveData<HashMap<Category, List<SubCategory>>> {
val data = MutableLiveData<HashMap<Category, List<SubCategory>>>()
val hashMap: HashMap<Category, List<SubCategory>> = hashMapOf()
Executors.newSingleThreadExecutor().execute {
for (category in categoryDao.getList()) {
hashMap[category] = subCategoryDao.getSubCategoriesListForCategory(category.id)
}
}
data.value = hashMap
return data
}
}
然后我在视图模型的 init{}
块中使用了它,例如:
hashMap = categorySubCategoryRepository.getHashMap()
然后我在 Fragment 的 onCreateView
中观察到它是:
myViewModel.hashMap.observe(this, Observer {
adapter.setCategoryList(it.keys.toList())
adapter.setCategorySubCategoriesMap(it)
elv_categories.setAdapter(adapter)
adapter.notifyDataSetChanged()
})
如果这不是正确的做法,请发表评论。我这样做只是为了提高我的技能,并且很想知道是否有更好的方法来处理事情,或者我的方法是否完全荒谬。
编辑:
根据@SanlokLee 的评论。 getHashMap
函数已更改为:
fun getHashMap(): LiveData<HashMap<Category, List<SubCategory>>> {
val data = MutableLiveData<HashMap<Category, List<SubCategory>>>()
Executors.newSingleThreadExecutor().execute {
val hashMap: HashMap<Category, List<SubCategory>> = hashMapOf()
for (category in categoryDao.getList()) {
hashMap[category] = subCategoryDao.getSubCategoriesListForCategory(category.id)
}
data.postValue(hashMap)
}
return data
}
所以我正在开发这个愚蠢的小应用程序来练习 MVVM 和存储库模式。我现在有两个模型 类。它们是 Category
和 SubCategory
,我为其定义了以下数据 类:
@Entity(tableName = "categories")
data class Category(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int,
@ColumnInfo(name = "name")
val name: String
) {
}
和
/**
* One to many Relationship from Category to SubCategory
*/
@Entity(
tableName = "sub_categories", foreignKeys = arrayOf(
ForeignKey(
entity = Category::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("category_id")
)
)
)
data class SubCategory(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int,
@ColumnInfo(name = "name")
val name: String,
@ColumnInfo(name = "category_id")
val categoryId: Int
) {
}
如您所见,我对资源进行了建模,因此我们需要传递 categoryId 以获取与类别相关的子类别。
现在我对这个 MVVM 和 LiveData 以及存储库模式还很陌生。
我的问题是我正在使用 ExpandableListView
来填充类别下的子类别,而 Adapter
需要 HashMap<Category, List<SubCategory>
才能显示可扩展的列表视图。
所以我的问题是如何使用 db->dao->repository->viewmodel
的方法从我的数据库中获取 HashMap<Category, List<SubCategory>
以及 adpater
的位置。
我想创建一个像 CategorySubCategoryRespository
这样的单独的存储库,这样我就可以执行以下操作不会有帮助吗?:
class CategorySubCategoryRepository(
private val categoryDao: CategoryDao,
private val subCategoryDao: SubCategoryDao
) {
val allCategoriesSubCategories: LiveData<HashMap<Category, List<SubCategory>>>
get() {
val hashMap: HashMap<Category, List<SubCategory>> = hashMapOf()
for (category in categoryDao.getList()) {
hashMap[category] = subCategoryDao.getSubCategoriesListForCategory(category.id)
}
return hashMap
}
}
}
PS:我想尽可能使用LiveData
所以我最终做的是,在我的 CategorySubcategoryRepository
中,我从 CategoryDao
和 SubcategoryDao
构建了 Hashmap,如下所示:
class CategorySubCategoryRepository(
private val categoryDao: CategoryDao,
private val subCategoryDao: SubCategoryDao
) {
fun getHashMap(): LiveData<HashMap<Category, List<SubCategory>>> {
val data = MutableLiveData<HashMap<Category, List<SubCategory>>>()
val hashMap: HashMap<Category, List<SubCategory>> = hashMapOf()
Executors.newSingleThreadExecutor().execute {
for (category in categoryDao.getList()) {
hashMap[category] = subCategoryDao.getSubCategoriesListForCategory(category.id)
}
}
data.value = hashMap
return data
}
}
然后我在视图模型的 init{}
块中使用了它,例如:
hashMap = categorySubCategoryRepository.getHashMap()
然后我在 Fragment 的 onCreateView
中观察到它是:
myViewModel.hashMap.observe(this, Observer {
adapter.setCategoryList(it.keys.toList())
adapter.setCategorySubCategoriesMap(it)
elv_categories.setAdapter(adapter)
adapter.notifyDataSetChanged()
})
如果这不是正确的做法,请发表评论。我这样做只是为了提高我的技能,并且很想知道是否有更好的方法来处理事情,或者我的方法是否完全荒谬。
编辑:
根据@SanlokLee 的评论。 getHashMap
函数已更改为:
fun getHashMap(): LiveData<HashMap<Category, List<SubCategory>>> {
val data = MutableLiveData<HashMap<Category, List<SubCategory>>>()
Executors.newSingleThreadExecutor().execute {
val hashMap: HashMap<Category, List<SubCategory>> = hashMapOf()
for (category in categoryDao.getList()) {
hashMap[category] = subCategoryDao.getSubCategoriesListForCategory(category.id)
}
data.postValue(hashMap)
}
return data
}