【问题标题】:BMI ViewModel Calculator Written in Kotlin用 Kotlin 编写的 BMI ViewModel 计算器
【发布时间】:2021-11-13 06:32:34
【问题描述】:

您好,我正在尝试更新基于用户输入计算用户 BMI 的基本 Kotlin 代码。我已经通过developer.android codelab实践了,还是下不了。

供参考HERE 是指向原始代码的链接,该代码已通过正确的计算得到修复,因此它正在运行。

但现在我想使用 ViewModel,以便在配置更改时保存 UI 数据。但到目前为止,这就是我所拥有的,因为我知道 ViewModel 需要保存数据处理代码并将 UI 数据留在常规类中很好,因为这只会处理 UI。

我不知道如何绑定所有数据或从 ViewModel 类正确访问它。如果有人可以提供帮助。如果需要在此处添加我的原始代码以便于访问,我可以添加它,我只是不想将它们全部聚集在一起。请有人帮忙!

'''

class bmiViewModel : ViewModel() {


val height = findViewById<EditText>(R.id.heightEditText)
val weight = findViewById<EditText>(R.id.weightEditText)

calcButton.setOnClickListener{
    var heightValue = 0.0
    var weightValue = 0.0
    if(height.text.toString().isNotEmpty()){
        heightValue = height.text.toString().toDouble()
    }
    if(weight.text.toString().isNotEmpty()){
        weightValue = weight.text.toString().toDouble()
    }

    if(weightValue > 0.0 && heightValue > 0.0){
        val bmiValue = String.format(" %.2f",
            (weightValue*703)/(heightValue*heightValue))
        
        val bmiDouble = bmiValue.toDouble()
        bmiInfo.text = "BMI is ${String.format("%.2f",bmiDouble)} you are " +
                       "${bmiResults((weightValue*703)/(heightValue*heightValue))}"
        bmiInfo.visibility = View.VISIBLE
    }
    else {
        Toast.makeText(
            this, "Please input Weight and Height Values greater than 0",
            Toast.LENGTH_LONG).show()
    }
}

// function to decide users BMI status
private fun bmiResults(bmi:Double):String{
    lateinit var answer: String
    if(bmi<18.5){
        answer="Underweight"
    } else if(bmi > 18.5 && bmi < 24.9) {
        answer="Normal"
    } else if(bmi > 24.9 && bmi < 30) {
        answer="Overweight"
    } else {
        answer="Obese"
    }
    return answer
}

} '''

【问题讨论】:

  • 您不应访问视图 (findViewById) 或在 ViewModel 中编辑它们。 ViewModel 应该进行相关计算,但视图/按钮的实际接口应该在您的活动或片段中。我建议通过tutorial 或阅读LiveData docsViewModel docs
  • 我觉得你在这里有点困惑。 ViewModel 用于保存数据,它不应该负责 UI 的工作。为此,您有 activityfragment。所以所有的业务逻辑(即计算应该在ViewModel中完成,而UI部分应该在活动或片段中完成。因此在activity/fragment类中使用FindViewById

标签: android kotlin mvvm viewmodel android-viewmodel


【解决方案1】:

您的ViewModel 应包含 2 个MutableLiveData 用于heightweight

您应该在Fragment/Activity 中将 2 个TextWatchers 添加到您的EditTexts。

TextWatchers上调用afterTextChanged时,使用ViewModelMutableLiveData设置对应数据的值。

内部Fragment/Activity

   private val heightTextWatcher = object : TextWatcher {
      override fun afterTextChanged(s: Editable?) {
          viewModel.height.setValue(s.toString())
      }
      override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
      override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}


   private val weightTextWatcher = object : TextWatcher {
      override fun afterTextChanged(s: Editable?) {
          viewModel.weight.setValue(s.toString())
      }
      override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
      override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

内部ViewModel

public var height: MutableLiveData<String> = MutableLiveData()
public var weight: MutableLiveData<String> = MutableLiveData()

fun onCalculate(){
    h = height.getValue()
    w = weight.getValue()
    //do math
}

数据永远不会离开ViewModelView 永远不会离开Fragment/Activity

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    相关资源
    最近更新 更多