我有一个用于两种不同类型的类别的选项卡布局:收入和费用。我使用 CategoriesViewModel 获取所有类别,并观察列表是否有任何更改。选择选项卡后,我会过滤类别,以便它们正确显示在该选项卡中,删除所有观察者并添加新观察者。问题是:
Fragment 的 onViewCreated():
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val categoriesRV = view.findViewById<RecyclerView>(R.id.categories_recycler_view)
currentTab = arguments?.getString("currentTab") ?: "income"
val tabLayout = view.findViewById<TabLayout>(R.id.type_tab_layout)
for (i in 0 until tabLayout.tabCount) {
val tab = tabLayout.getTabAt(i)
val tabText = tab?.text?.toString()?.lowercase()
if (tabText == currentTab) {
tabLayout.selectTab(tab)
}
}
categoryVM.getAllCategories().observe(viewLifecycleOwner) { categories ->
val filteredCategories = filterCategories(categories, currentTab)
val categoriesAdapter = CategoriesAdapter(filteredCategories, this)
categoriesRV.adapter = categoriesAdapter
}
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
currentTab = tab?.text.toString().lowercase()
if (categoryVM.getAllCategories().hasObservers()) categoryVM.getAllCategories().removeObservers(viewLifecycleOwner)
categoryVM.getAllCategories().observe(viewLifecycleOwner) { categories ->
val filteredCategories = filterCategories(categories, currentTab)
val categoriesAdapter =
CategoriesAdapter(filteredCategories, this@CategoriesFragment)
categoriesRV.adapter = categoriesAdapter
}
}
override fun onTabReselected(tab: TabLayout.Tab?) {
// Handle tab reselect
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
// Handle tab unselect
}
})
val newCategoryButton = view.findViewById<Button>(R.id.new_category_button)
newCategoryButton.setOnClickListener {
openCategoryDialog(null) {
categoryVM.addCategory(it.name, it.iconId, currentTab)
}
}
}
类别适配器:
class CategoriesAdapter(
private var categoryList: List<Category>,
private val deleteClickListener: OnCategoryDeleteClickListener
) : RecyclerView.Adapter<CategoriesAdapter.CategoriesViewHolder>() {
class CategoriesViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val categoryName: TextView
val categoryIcon: ImageView
val deleteBadge: ImageButton
init {
categoryName = view.findViewById(R.id.category_name)
categoryIcon = view.findViewById(R.id.category_icon)
deleteBadge = view.findViewById(R.id.badgeIcon)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoriesViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_category, parent, false)
return CategoriesViewHolder(view)
}
override fun onBindViewHolder(holder: CategoriesViewHolder, position: Int) {
val category = categoryList[position]
holder.categoryName.text = category.name
holder.categoryName
if (category.iconId != null) {
holder.categoryIcon.visibility = View.VISIBLE
holder.categoryIcon.setImageResource(category.iconId)
val layoutParams = holder.categoryIcon.layoutParams
layoutParams.width = 130 // Adjust the width as per your requirement
layoutParams.height = 130 // Adjust the height as per your requirement
holder.categoryIcon.layoutParams = layoutParams
}
holder.deleteBadge.setOnClickListener {
deleteClickListener.onDeleteClick(category)
}
}
override fun getItemCount() = categoryList.size
}
interface OnCategoryDeleteClickListener {
fun onDeleteClick(category: Category)
}
首先,你的视图正在进行排序。这应该由视图模型来完成。因此,从视图模型中将交易过滤为费用列表和收入列表,并在各自的选项卡中观察两者。当您添加新项目(费用或收入)时,请写入列表和数据库(异步,如果需要,您必须有一些重试机制)。 使用两个单独的列表,不会有重复的数据,解决了问题 1。通过将其同时写入数据库和列表,您不必依赖选项卡选择来确定要添加的内容,而是每个片段都会调用他们各自的 addExpense,addIncome 方法。