它的工作原理是这样的:用户在NewBudgetFragment中添加新的预算项。该项将在recyclerview中显示在BudgetFragment中。预算项具有amountSpent变量,每当用户添加新的交易时(这发生在另一个片段中),该变量应更新。但是,在创建预算项之后,如果用户在该特定类别上花费了钱,则recyclerview项中的amountSpent不会得到更新。我已经在BudgetAdapter中使用了LiveData和DiffUtil,但我无法弄清楚为什么它没有得到更新。
这是BudgetAdapter:
class BudgetAdapter() : ListAdapter<Budget, BudgetAdapter.BudgetViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BudgetViewHolder {
val binding =
BudgetItemLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BudgetViewHolder(binding)
}
override fun onBindViewHolder(holder: BudgetViewHolder, position: Int) {
val currentItem = getItem(position)
holder.bind(currentItem, position)
}
class BudgetViewHolder(val binding: BudgetItemLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(budget: Budget, position: Int) {
binding.apply {
tvBudgetName.text = budget.name
tvBudgetLimit.text = budget.limit.toString()
tvAmountSpent.text = budget.amountSpent.toString()
tvPercentageSpent.text = ((budget.amountSpent/budget.limit)*100).toInt().toString() + "%"
}
}
}
class DiffCallback : DiffUtil.ItemCallback<Budget>() {
override fun areItemsTheSame(oldItem: Budget, newItem: Budget): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Budget, newItem: Budget): Boolean {
return oldItem == newItem
}
}
}
以下是创建新预算项的方法: NewBudgetFragment:
...
viewModel.transactions.observe(viewLifecycleOwner) { it ->
transactionList = it.filter { it.category == listCategory[selectedCategoryIndex].name }
amountSpent = transactionList.sumOf { it.amount }
}
...
if (budgetName.isNotEmpty() && budgetLimit.isNotEmpty() && budgetCategory != null) {
viewModel.addBudget(
name = budgetName,
limit = budgetLimit.toDouble(),
amountSpent=amountSpent,
category = budgetCategory.name)
这是BudgetFragment.kt文件,适配器在其中:
class BudgetFragment : Fragment(R.layout.fragment_budget),BudgetAdapter.OnItemClickListener {
private lateinit var binding: FragmentBudgetBinding
private val viewModel: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentBudgetBinding.bind(view)
val budgetAdapter = BudgetAdapter(this)
val toolbar = binding.toolbar.root
toolbar.title = "Budget"
(requireActivity() as MainActivity).setSupportActionBar(toolbar)
binding.apply {
rvBudget.apply {
adapter = budgetAdapter
setHasFixedSize(true)
}
}
viewModel.budgets.observe(viewLifecycleOwner){
if(it.isNotEmpty()){
binding.rvBudget.visibility = View.VISIBLE
binding.tvNoBudget.visibility = View.INVISIBLE
}else{
binding.rvBudget.visibility = View.INVISIBLE
binding.tvNoBudget.visibility = View.VISIBLE
}
budgetAdapter.submitList(it)
}
binding.btAddBudget.setOnClickListener {
val action = BudgetFragmentDirections.actionBudgetFragmentToNewBudgetFragment()
findNavController().navigate(action)
}
}
ViewModel
中实现addBudget
方法?确保每次添加预算时创建一个新的预算列表。当你向已经提交给budgetAdapter
的当前预算中添加新的预算时,DiffUtil
将把它视为相同的列表,这就是为什么你的列表不会更新的原因。这是因为在 Java/Kotlin 中,当你把一个List
作为参数传递时,它是按引用传递的。 - Sovathna Hong