如何在两个不同的选项卡中处理相同的数据

问题描述 投票:0回答:1

我有一个用于两种不同类型的类别的选项卡布局:收入和费用。我使用 CategoriesViewModel 获取所有类别,并观察列表是否有任何更改。选择选项卡后,我会过滤类别,以便它们正确显示在该选项卡中,删除所有观察者并添加新观察者。问题是:

  • 更改选项卡时,有时会显示所选选项卡中的类别,就好像以前的类别仍然存在一样List of categories with empty space above them。因此,它们上方会有一个空白区域,就好像其他类别在那里,但实际上它们不在那里。
  • 当添加/删除类别(在特定选项卡上)时,有时,另一个选项卡中的类别会出现在那里,并且实际上是使用当前选项卡类型在数据库中创建的(例如,我有 3 个收入类别,当从费用选项卡,(我不知道是什么触发了这个错误),有时,这 3 个收入类别会复制到费用类别)。

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)
}
android kotlin android-recyclerview android-livedata android-tablayout
1个回答
0
投票

首先,你的视图正在进行排序。这应该由视图模型来完成。因此,从视图模型中将交易过滤为费用列表和收入列表,并在各自的选项卡中观察两者。当您添加新项目(费用或收入)时,请写入列表和数据库(异步,如果需要,您必须有一些重试机制)。 使用两个单独的列表,不会有重复的数据,解决了问题 1。通过将其同时写入数据库和列表,您不必依赖选项卡选择来确定要添加的内容,而是每个片段都会调用他们各自的 addExpense,addIncome 方法。

© www.soinside.com 2019 - 2024. All rights reserved.