在 kotlin 中单击按钮时更改 ViewModel 中的字符串值,然后将该值存储在房间数据库中

Change String Value in ViewModel on button click in kotlin then store the value in room db

我正在尝试将 debtCategory 的值更改为“贷款人”或“借款人”。我在我的视图模型中引入了两种方法来更新 debtCategory。这是逻辑:

到目前为止没有错误,但是 debtCatery 没有相应地更新。非常感谢您的帮助。

提前致谢

这是我的代码:

1.视图模型

import android.content.Context
import android.text.Editable
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.AutoCompleteTextView
import androidx.databinding.Bindable
import androidx.databinding.Observable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.droid.f.debtmanagement.R
import com.droid.f.debtmanagement.models.Debtor
import com.droid.f.debtmanagement.repository.DebtManagementRepository
import com.droid.f.debtmanagement.util.Util
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

class DebtViewModel(private val debtManagementRepository: DebtManagementRepository)
    : ViewModel(),Observable {
    //all debtors
    val allLenders = debtManagementRepository.getAllLenders()
    val allBorrowers = debtManagementRepository.getAllBorrowers()

    private val util = Util()

    var debtCategory: String = ""

    @Bindable
    val clientName = MutableLiveData<String>()
    @Bindable
    val phoneNumber = MutableLiveData<String>()
    @Bindable
    val debtorAmount = MutableLiveData<String>()
    @Bindable
    val amountPaid = MutableLiveData<String>()
    @Bindable
    val period = MutableLiveData<String>()
    private val datelend = MutableLiveData<String>()
    private val dateToPay = MutableLiveData<String>()
    private val debtStatus = MutableLiveData<String>()
    private val timeBorrowed = MutableLiveData<String>()
    private val remainingAmount = MutableLiveData<Double>()

    init {
        debtStatus.value = "Pending"
    }

    fun saveUpdate(){
        val debtorName: String = clientName.value!!
        val debtorPhone: String = phoneNumber.value!!
        val debtAmount: Double = debtorAmount.value!!.toDouble()
        val period: Int = monthsToDays()
        val debtAmountPaid: Double = amountPaid.value!!.toDouble()
        val debtorDateLend: String = dateBorrowedLend()
        val debtorDateToPay: String = _dueDate()
        val debtorStatus: String = checkProgress()
        val debtTimeBorrowed: String = exactTimeBorrowed()
        val remainingAmount: Double = remainingAmount()
        val dtCategory: String = debtCategory

        insertDebtor(
            Debtor(
            0, dtCategory, debtorName, debtorPhone, debtAmount, debtAmountPaid,period, debtorDateLend, debtorDateToPay, debtorStatus,
            debtTimeBorrowed, remainingAmount
        ))
        clearFields()
    }

    fun clearFields(){
        clientName.value = null
        phoneNumber.value = null
        debtorAmount.value = null
        period.value = null
        amountPaid.value = null
    }

    fun updateLender(){
        debtCategory = "Lender"
    }

    fun updateBorrower(){
        debtCategory = "Borrower"
    }
    //Months to Date
    private fun monthsToDays(): Int{
        return util.monthsToDays(period.value!!.toInt())
    }
    //Date borroewed/lend
    private fun dateBorrowedLend(): String{
        return util.dateNow()
    }

    //Time borrowed/lend
    private fun exactTimeBorrowed(): String{
        return util.timeNow()
    }
    //Due date method
    private fun _dueDate(): String{
        return util.dueDate(util.monthsToDays(period.value!!.toInt()))
    }
    //remaining amount method
    private fun remainingAmount(): Double{
        return util.remainingDebt(debtorAmount.value!!.toDouble(), amountPaid.value!!.toDouble())
    }

    //check progress
    private fun checkProgress(): String{
        return util.checkProgress(debtorAmount.value!!.toDouble(), amountPaid.value!!.toDouble())
    }

    private fun insertDebtor(debtor: Debtor): Job = viewModelScope.launch {
            debtManagementRepository.insertDebtor(debtor)
    }

    fun updateDebtor(debtor: Debtor): Job = viewModelScope.launch {
        debtManagementRepository.updateDebtor(debtor)
    }

    fun deleteDebtor(debtor: Debtor): Job = viewModelScope.launch {
        debtManagementRepository.deleteDebtor(debtor)
    }

    fun deleteAllDebtors(): Job = viewModelScope.launch {
        debtManagementRepository.deleteAllDebtors()
    }

    override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {

    }

    override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {

    }

}

2。主要活动:

class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
private var mDebtViewModel: DebtViewModel? = null
private lateinit var repository: DebtManagementRepository
private lateinit var factory: DebtManagementViewModelFactory
private lateinit var debtDatabase: DebtManagementDatabase

//initialize animation files
private val rotateOpen: Animation by lazy{ AnimationUtils.loadAnimation(this, R.anim.rotate_to_open_anim)}
private val rotateToClose: Animation by lazy { AnimationUtils.loadAnimation(this, R.anim.rotate_to_close_anim) }
private val fromBottom: Animation by lazy { AnimationUtils.loadAnimation(this, R.anim.from_bottom_anim) }
private val toBottom: Animation by lazy { AnimationUtils.loadAnimation(this, R.anim.to_bottom_anim) }

private var isOpen: Boolean = false

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    debtDatabase = DebtManagementDatabase.getDataBase(this)
    repository = DebtManagementRepository(debtDatabase)
    factory = DebtManagementViewModelFactory(repository)
    mDebtViewModel = ViewModelProvider(this, factory).get(DebtViewModel::class.java)
    binding.debtViewModel = mDebtViewModel
    binding.lifecycleOwner = this

    binding.addFab.setOnClickListener {
        onAddFabClicked()
    }

    binding.addLender.setOnClickListener {
        newDebtorActivity()
        mDebtViewModel!!.updateLender()
    }

    binding.addBorrower.setOnClickListener {
        newDebtorActivity()
        mDebtViewModel!!.updateBorrower()
    }

    addTabsAndIntializePager()
}

private fun onAddFabClicked() {
    setVisibility(isOpen)
    setAnimation(isOpen)
    isOpen = !isOpen
}

private fun setVisibility(isOpen: Boolean) {
    if (!isOpen){
        binding.addBorrower.visibility = View.VISIBLE
        binding.addLender.visibility = View.VISIBLE
    }else{
        binding.addBorrower.visibility = View.INVISIBLE
        binding.addLender.visibility = View.INVISIBLE
    }
}

private fun setAnimation(isOpen: Boolean) {
    if (!isOpen){
        binding.addFab.startAnimation(rotateOpen)
        binding.addLender.startAnimation(fromBottom)
        binding.addBorrower.startAnimation(fromBottom)
    }else{
        binding.addFab.startAnimation(rotateToClose)
        binding.addLender.startAnimation(toBottom)
        binding.addBorrower.startAnimation(toBottom)
    }
}

private fun newDebtorActivity() {
    startActivity(Intent(this, EditActivity::class.java))
    binding.addBorrower.visibility = View.INVISIBLE
    binding.addLender.visibility = View.INVISIBLE
}

private fun addTabsAndIntializePager() {
    binding.viewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
    TabLayoutMediator(binding.debtManagementTab, binding.viewPager){tab, position->
        when(position){
            0->{
               tab.text = "Borrowers"
            }
            1->{
                tab.text = "Lenders"
            }
        }
    }.attach()
}

}

你的Viewmodelclass没问题。 问题出在 MainActivity 中的 2 个方法上 在这里,您在更新值之前导航下一个 activity。您需要在调用 newDebtorActivity()

之前调用 mDebtViewModel!!.updateLender()mDebtViewModel!!.updateBorrower()

这是您的代码

binding.addLender.setOnClickListener {
        newDebtorActivity()
        mDebtViewModel!!.updateLender()
    }

    binding.addBorrower.setOnClickListener {
        newDebtorActivity()
        mDebtViewModel!!.updateBorrower()
    }

应该是

binding.addLender.setOnClickListener {
        mDebtViewModel!!.updateLender()
        newDebtorActivity()
        
    }

    binding.addBorrower.setOnClickListener {
        mDebtViewModel!!.updateBorrower()
        newDebtorActivity()
    }

与其将 debtCategory 设为字符串,不如将其更改为可变的实时数据

...
    // from var debtCategory: String = ""
    // change it to
    val debtCategory = MutableLiveData<String>()
...

比 make 函数更新它

    fun updateDebtCategory(newValue: String){
        debtCategory.value = newValue
    }

您可以在 activity

中调用它
viewModel.updateDebtCategory("Borrower")
//or
viewModel.updateDebtCategory("Lander")