3
\$\begingroup\$

I have made a Body mass index-calculator using ViewModel and LiveData.

Screenshot 1

Screenshot 2

Source-code of the MainActivity:

package com.example.bmirechner

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.SeekBar
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.bmirechner.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: BmiViewModel

    fun updateUi() {
        val bmi = viewModel.computeBmi()
        binding.resultTextView.text = bmi.toString()

        var messageText = ""
        when {
            bmi < 20 -> messageText = resources.getString(R.string.text_underweight)
            bmi in 20.0..25.0 -> messageText = resources.getString(R.string.text_normal_weight)
            bmi > 25 && bmi <= 30 -> messageText = resources.getString(R.string.text_overweight)
            bmi > 30 -> messageText = resources.getString(R.string.text_heavy_overweight)
            else -> messageText = resources.getString(R.string.error)
        }

        binding.messageTextView.text = messageText
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        viewModel = ViewModelProvider(this).get(BmiViewModel::class.java)

        binding.currentWeightTextView.text = viewModel.getCurrentWeight().value.toString()
        binding.currentHeightTextView.text = viewModel.getCurrentHeight().value.toString()

        binding.heightSeek.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                viewModel.setCurrentHeight(progress.toDouble())
                viewModel.getCurrentHeight().observe(this@MainActivity, Observer {
                    binding.currentHeightTextView.text = it.toString()
                })
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                updateUi()
            }
        })

        binding.weightSeek.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                viewModel.setCurrentWeight(progress.toDouble())
                viewModel.getCurrentWeight().observe(this@MainActivity, Observer {
                    binding.currentWeightTextView.text = it.toString()
                })
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}
            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                updateUi()
            }
        })
    }
}

Source-Code of the ViewModel:

package com.example.bmirechner

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import kotlin.math.pow
import kotlin.math.round

class BmiViewModel: ViewModel() {
    private var currentHeight = MutableLiveData<Double>()
    private var currentWeight = MutableLiveData<Double>()

    init {
        currentHeight.value = 0.0
        currentWeight.value = 0.0
    }

    fun setCurrentHeight(value: Double) {
        currentHeight.value = value
    }

    fun setCurrentWeight(value: Double) {
        currentWeight.value = value
    }

    fun getCurrentHeight(): MutableLiveData<Double> {
        return currentHeight
    }

    fun getCurrentWeight(): MutableLiveData<Double> {
        return currentWeight
    }

    fun computeBmi(): Double {
        val factor = 10
        val heightInMeter = currentHeight.value!! / 100.0
        val bmi = currentWeight.value!! / heightInMeter.pow(2)
        return round(bmi * factor) / factor
    }
}

Is my LiveData-usage correct or should it be modified?

What parts of my implementation could be improved?

Looking forward to reading your comments and answers.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Perhaps add instruction related to units used for height/weight :) (cm/kg) \$\endgroup\$
    – hjpotter92
    Dec 28, 2021 at 12:20
  • \$\begingroup\$ @hjpotter92 Thanks. I really should have done so. \$\endgroup\$ Dec 28, 2021 at 13:02
  • \$\begingroup\$ i would appreciate if you had put the actions from your slider into a method and could avoid the redundant code. (that far to little for a whole review - its just a side note ^^) \$\endgroup\$ Feb 14, 2022 at 19:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.