android - LiveData 观察者调用了两次
问题描述
我有一个名为的片段loanFragment
,它根据付款次数计算并显示应付贷款的剩余金额。它有一个名为 viewmodel LoanViewModel
,其中包含remainingAmount
和loanPayments
livedata。loanFragment
我在for the中设置了观察者,remainingAmount
这样loanPayments
每当这些数据发生变化时,就会触发剩余金额的计算,并相应loanFragment
地更新 UI。
问题是如果我导航到另一个片段然后导航回loanFragment
,观察者loanPayments
被调用两次,这也导致计算剩余量两次。另一方面,观察者remainingAmount
工作正常。该问题仅发生在 loanPayments
. 仅在loanPayments
从后端获取付款后才修改实时数据。但是在导航回 之后,即使尚未触发支付的获取,也会调用loanFragment
观察者。loanPayments
然后在提取贷款付款完成后再次调用它。loanFragment
请注意,第一次打开时不会出现问题。我不确定我错过了什么或我的代码中的错误在哪里。
LoanFragment
代码:
class LoanFragment : Fragment() {
private val loanViewModel: LoanViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_loan, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Init data
loanViewModel.remainingAmount.observe(viewLifecycleOwner, { remainingAmount ->
setUpRemainingAmount(view, remainingAmount)
})
loanViewModel.loanPayments.observe(viewLifecycleOwner, { payments ->
loanViewModel.remainingAmount.value?.let {
var remainingAmount = it
payments.forEach { payment -> remainingAmount -= payment.amount }
loanViewModel.remainingAmount.value = remainingAmount
}
})
loanViewModel.selectedLoan.value?.let { loan ->
loanViewModel.remainingAmount.value = loan.amount
loanViewModel.fetchLoanPayments(loan.uid)
}
}
private fun setUpRemainingAmount(view: View, remainingAmount: Double) {
val tvRemainingAmount: TextView = view.findViewById(R.id.tvRemainingAmount)
val formatter = DecimalFormat("#,###.00")
val amount = "₱" + formatter.format(loanViewModel.remainingAmount.value)
tvRemainingAmount.text = amount
}
}
LoanViewModel
代码:
@HiltViewModel
class LoanViewModel @Inject constructor(
private val paymentRepository: PaymentRepository,
) : ViewModel() {
val loanPayments = MutableLiveData<MutableList<Payment>>()
val selectedLoan = MutableLiveData<Loan>()
var remainingAmount = MutableLiveData<Double>()
fun fetchLoanPayments(uid: String) {
val task = paymentRepository.fetchLoanPayments(uid)
task.addOnSuccessListener { result ->
val payments = mutableListOf<Payment>()
for (document in result)
Payment(document.data as HashMap<*, *>).let(payments::add)
loanPayments.value = payments
}.addOnFailureListener { e ->
Utils.print("Error getting documents: " + e.message)
}
}
}
我还在LoanPaymentsFragment
. 它是 的子片段LoanFragment
。它的责任是只显示付款。我不确定它是否相关,但我想也包括它的代码。
class LoanPaymentsFragment : Fragment() {
private lateinit var paymentsRvAdapter: PaymentsRvAdapter
private val paymentsList = mutableListOf<Payment>()
private val loanViewModel: LoanViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_loan_payments, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Payments list listener
loanViewModel.loanPayments.observe(viewLifecycleOwner, {
paymentsList.clear()
paymentsList.addAll(it)
paymentsRvAdapter.notifyDataSetChanged()
})
setUpRecyclerView(view)
}
}
解决方案
推荐阅读
- powerquery - PowerQuery - 在列表中搜索多个首字母缩写词
- docker - 使用 Nginx for Kafka 进行端口转发
- charts - 创建数据集时出错:无法创建数据集
- postgresql - 查询索引:单列索引与复合索引:哪一个是好的做法,也可以提供更快的性能
- c# - zpl 200dpi和300dpi有什么区别?
- node.js - 在基于 AWS ECS 路径的路由中部署节点后,套接字 IO 未连接
- java - Select * From java with prepareStatement
- android-12 - 不受信任的触摸事件被阻止 Android 12
- python - 如何使用 python 的 requests.Session.get(而不是 requests.get)避免或处理过期错误
- python - 如何改变fastai中混淆矩阵的大小?