Home > Mobile >  How to do multiple operations at a time in calculator app
How to do multiple operations at a time in calculator app

Time:10-30

this is the function for dialing numbers. resultTextview variable is what's displayed when someone inputs number numbers. variable stores every action user takes and displays it

`

fun numberclick(clickedView: View) {
    if(clickedView is TextView) {

        var text = resultTextview.text.toString()
        var textN = numbers.text.toString()
        var number = clickedView.text.toString()

        if (text == "0" || textN == "0") {
            text = ""
            textN = ""
        }
        val result = text   number
        val resultN = textN   number
        resultTextview.text = result
        numbers.text = resultN
    }
}

this code works but when i try to do multiple operations without hitting equals it fails

fun operationclick(clickedView: View) {
    if(clickedView is TextView){
        var numresult = numbers.text.toString()   clickedView.text.toString()
        this.operant = resultTextview.text.toString().toDouble()
        this.operation = clickedView.text.toString()
        resultTextview.text = ""
        numbers.text = numresult   resultTextview.text
    }
}
fun equals(clickedView: View) {
    if (clickedView is TextView){
        val secondoperant = resultTextview.text.toString().toDouble()
        when (operation) {
            " " -> resultTextview.text = (this.operant   secondoperant).toString()
            "-" -> resultTextview.text = (this.operant - secondoperant).toString()
            "/" -> resultTextview.text = (this.operant / secondoperant).toString()
            "X" -> resultTextview.text = (this.operant * secondoperant).toString()
        }
    }
}

`

i tried to change returnTextView to Numbers variable in this.operator but the app crashes when i do that.

CodePudding user response:

Best guess, you're doing these in the wrong order:

        resultTextview.text = ""
        numbers.text = numresult   resultTextview.text

By clearing the text on the first line, the concatenation on the next line has no effect.

Wider recommendation: you shouldn't be messing with the content of views in the listeners for views. What you should do is make a Model object which contains the state of the calculator, and get that tested first. Then when you build the view, you just poke at the methods on the Model which are already working. This way, you don't have to try and debug view-level issues and model-level issues at the same time.

CodePudding user response:

Without know exactly what you are doing its hard to tell what the issue is. So i am just throwing this out here for a reference, but it is a working calculator i have on Google Play. Your layout may be different but the code is accurate for the functions

class MainActivity : AppCompatActivity() {
private val button0: Button by bind(R.id.button_0)
private val button1: Button by bind(R.id.button_1)
private val button2: Button by bind(R.id.button_2)
private val button3: Button by bind(R.id.button_3)
private val button4: Button by bind(R.id.button_4)
private val button5: Button by bind(R.id.button_5)
private val button6: Button by bind(R.id.button_6)
private val button7: Button by bind(R.id.button_7)
private val button8: Button by bind(R.id.button_8)
private val button9: Button by bind(R.id.button_9)

private val buttonMemoryClear: Button by bind(R.id.button_memory_clear)
private val buttonMemoryRecall: Button by bind(R.id.button_memory_recall)
private val buttonMemoryAdd: Button by bind(R.id.button_memory_add)
private val buttonMemorySubtract: Button by bind(R.id.button_memory_subtract)
private val buttonMemoryStore: Button by bind(R.id.button_memory_store)
private val MemoryNumber: TextView by bind(R.id.tvmemory)

private val buttonPercentage: Button by bind(R.id.button_percentage)
private val buttonRoot: Button by bind(R.id.button_root)
private val buttonSquare: Button by bind(R.id.button_square)
private val buttonFraction: Button by bind(R.id.button_fraction)
private val buttonCE: Button by bind(R.id.button_ce)
private val buttonC: Button by bind(R.id.button_c)
private val buttonBackspace: Button by bind(R.id.button_backspace)
private val buttonDivision: Button by bind(R.id.button_division)
private val buttonMultiplication: Button by bind(R.id.button_multiplication)
private val buttonSubtraction: Button by bind(R.id.button_subtraction)
private val buttonAddition: Button by bind(R.id.button_addition)
private val buttonEqual: Button by bind(R.id.button_equal)
private val buttonPlusMinus: Button by bind(R.id.button_plus_minus)
private val buttonComma: Button by bind(R.id.button_comma)

private val textViewHistoryText: TextView by bind(R.id.number_history)
private val textViewCurrentNumber: AppCompatTextView by bind(R.id.current_number)

private var isFutureOperationButtonClicked: Boolean = false
private var isInstantOperationButtonClicked: Boolean = false
private var isEqualButtonClicked: Boolean = false

private var currentNumber: Double = 0.0
private var currentResult: Double = 0.0
private var memory: Double = 0.0

private var historyText = ""
private var historyInstantOperationText = ""
private var historyActionList: ArrayList<String> = ArrayList()

private val ZERO: String = "0"
private val ONE: String = "1"
private val TWO: String = "2"
private val THREE: String = "3"
private val FOUR: String = "4"
private val FIVE: String = "5"
private val SIX: String = "6"
private val SEVEN: String = "7"
private val EIGHT: String = "8"
private val NINE: String = "9"

private val INIT = ""

private val ADDITION = "   "
private val SUBTRACTION = " − "
private val MULTIPLICATION = " × "
private val DIVISION = " ÷ "

private val PERCENTAGE = "%"
private val ROOT = "√"
private val SQUARE = "sqr"
private val FRACTION = "1/"

private val NEGATE = "negate"
private val Period = "."
private val EQUAL = " = "

private var currentOperation = INIT

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    button0.setOnClickListener {
        onNumberButtonClick(ZERO)
    }

    button1.setOnClickListener {
        onNumberButtonClick(ONE)
    }

    button2.setOnClickListener {
        onNumberButtonClick(TWO)
    }

    button3.setOnClickListener {
        onNumberButtonClick(THREE)
    }

    button4.setOnClickListener {
        onNumberButtonClick(FOUR)
    }

    button5.setOnClickListener {
        onNumberButtonClick(FIVE)
    }

    button6.setOnClickListener {
        onNumberButtonClick(SIX)
    }

    button7.setOnClickListener {
        onNumberButtonClick(SEVEN)
    }

    button8.setOnClickListener {
        onNumberButtonClick(EIGHT)
    }

    button9.setOnClickListener {
        onNumberButtonClick(NINE)
    }

    buttonAddition.setOnClickListener {
        onFutureOperationButtonClick(ADDITION)
    }

    buttonSubtraction.setOnClickListener {
        onFutureOperationButtonClick(SUBTRACTION)
    }

    buttonMultiplication.setOnClickListener {
        onFutureOperationButtonClick(MULTIPLICATION)
    }

    buttonDivision.setOnClickListener {
        onFutureOperationButtonClick(DIVISION)
    }

    buttonCE.setOnClickListener {
        clearEntry()
    }

    buttonC.setOnClickListener {
        currentNumber = 0.0
        currentResult = 0.0
        currentOperation = INIT

        historyText = ""
        historyInstantOperationText = ""

        textViewCurrentNumber.text = formatDoubleToString(currentNumber)
        textViewHistoryText.text = historyText

        isFutureOperationButtonClicked = false
        isEqualButtonClicked = false
        isInstantOperationButtonClicked = false
    }

    buttonBackspace.setOnClickListener {

        if (isFutureOperationButtonClicked || isInstantOperationButtonClicked || isEqualButtonClicked) return@setOnClickListener

        var currentValue: String = textViewCurrentNumber.text.toString()

        val charsLimit = if (currentValue.first().isDigit()) 1 else 2

        currentValue = if (currentValue.length > charsLimit)
            currentValue.substring(0, currentValue.length - 1)
        else
            ZERO

        textViewCurrentNumber.text = currentValue
        currentNumber = formatStringToDouble(currentValue)
    }

    buttonPlusMinus.setOnClickListener {

        val currentValue: String = textViewCurrentNumber.text.toString()

        currentNumber = formatStringToDouble(currentValue)
        if (currentNumber == 0.0) return@setOnClickListener

        currentNumber *= -1
        textViewCurrentNumber.text = formatDoubleToString(currentNumber)


        if (isInstantOperationButtonClicked) {
            historyInstantOperationText = "($historyInstantOperationText)"
            historyInstantOperationText = StringBuilder().append(NEGATE).append(historyInstantOperationText).toString()
            textViewHistoryText.text = StringBuilder().append(historyText).append(currentOperation).append(historyInstantOperationText).toString()
        }

        if (isEqualButtonClicked) {
            currentOperation = INIT
        }

        isFutureOperationButtonClicked = false
        isEqualButtonClicked = false
    }

    buttonComma.setOnClickListener {

        var currentValue: String = textViewCurrentNumber.text.toString()

        if (isFutureOperationButtonClicked || isInstantOperationButtonClicked || isEqualButtonClicked) {
            currentValue = StringBuilder().append(ZERO).append(Period).toString()
            if (isInstantOperationButtonClicked) {
                historyInstantOperationText = ""
                textViewHistoryText.text = StringBuilder().append(historyText).append(currentOperation).toString()
            }
            if (isEqualButtonClicked) currentOperation = INIT
            currentNumber = 0.0
        } else if (currentValue.contains(Period)) {
            return@setOnClickListener
        } else currentValue = StringBuilder().append(currentValue).append(Period).toString()

        textViewCurrentNumber.text = currentValue

        isFutureOperationButtonClicked = false
        isInstantOperationButtonClicked = false
        isEqualButtonClicked = false
    }

    buttonEqual.setOnClickListener {

        if (isFutureOperationButtonClicked) {
            currentNumber = currentResult
        }



        val historyAllText = calculateResult()

        //   Toast.makeText(applicationContext, historyAllText, Toast.LENGTH_LONG).show()

        historyActionList.add(historyAllText)

        historyText = StringBuilder().append(formatDoubleToString(currentResult)).toString()


        //   textViewHistoryText.text = StringBuilder().append(currentOperation).append((currentResult)).append(EQUAL).toString()




        isFutureOperationButtonClicked = false
        isEqualButtonClicked = true
    }

    buttonPercentage.setOnClickListener {
        onInstantOperationButtonClick(PERCENTAGE)


    }

    buttonRoot.setOnClickListener {
        onInstantOperationButtonClick(ROOT)
    }

    buttonSquare.setOnClickListener {
        onInstantOperationButtonClick(SQUARE)
    }

    buttonFraction.setOnClickListener {
        onInstantOperationButtonClick(FRACTION)
    }

    buttonMemoryClear.isEnabled = false
    buttonMemoryClear.setOnClickListener {

        MemoryNumber.text = "MR: "
        buttonMemoryClear.isEnabled = false
        buttonMemoryRecall.isEnabled = false

        memory = 0.0

    }

    buttonMemoryRecall.isEnabled = false
    buttonMemoryRecall.setOnClickListener {

        MemoryNumber.text = memory.toString()
        clearEntry(memory)

    }

    buttonMemoryAdd.setOnClickListener {



        buttonMemoryClear.isEnabled = true
        buttonMemoryRecall.isEnabled = true

        val currentValue: String = textViewCurrentNumber.text.toString()
        val thisOperationNumber: Double = formatStringToDouble(currentValue)
        val newMemory = memory   thisOperationNumber



        memory = newMemory
        MemoryNumber.text = "MR: $memory"

    }

    buttonMemorySubtract.setOnClickListener {

        MemoryNumber.text = ""
        buttonMemoryClear.isEnabled = true
        buttonMemoryRecall.isEnabled = true

        val currentValue: String = textViewCurrentNumber.text.toString()
        val thisOperationNumber: Double = formatStringToDouble(currentValue)

        val newMemory = memory - thisOperationNumber


        MemoryNumber.text = "MR: "
        memory = newMemory

    }

    buttonMemoryStore.setOnClickListener {

        val currentValue: String = textViewCurrentNumber.text.toString()
        memory = formatStringToDouble(currentValue)

        MemoryNumber.text = "MR: $memory"

        buttonMemoryClear.isEnabled = true
        buttonMemoryRecall.isEnabled = true

    }

}

@Throws(IllegalArgumentException::class)
private fun onNumberButtonClick(number: String, isHistory: Boolean = false) {

    var currentValue: String = textViewCurrentNumber.text.toString()
    currentValue = if (currentValue == ZERO || isFutureOperationButtonClicked || isInstantOperationButtonClicked || isEqualButtonClicked || isHistory) number else StringBuilder().append(currentValue).append(number).toString()

    try {
        currentNumber = formatStringToDouble(currentValue)
    } catch (e: ParseException) {
        throw IllegalArgumentException("String must be number.")
    }

    textViewCurrentNumber.text = currentValue

    if (isEqualButtonClicked) {
        currentOperation = INIT
        historyText = " "
    }

    if (isInstantOperationButtonClicked) {
        historyInstantOperationText = ""
        textViewHistoryText.text = StringBuilder().append(historyText).append(currentOperation).toString()
        isInstantOperationButtonClicked = false
    }

    isFutureOperationButtonClicked = false
    isEqualButtonClicked = false
}

private fun onFutureOperationButtonClick(operation: String) {

    if (!isFutureOperationButtonClicked && !isEqualButtonClicked) {
        calculateResult()

    }
    else if (isFutureOperationButtonClicked && isEqualButtonClicked){
        textViewHistoryText.text = currentResult.toString()
    }

    currentOperation = operation

    if (isInstantOperationButtonClicked) {
        isInstantOperationButtonClicked = false
        historyText = textViewHistoryText.text.toString()
    }
    textViewHistoryText.text = StringBuilder().append(historyText).append(operation).toString()

    isFutureOperationButtonClicked = true
    isEqualButtonClicked = false
}

private fun onInstantOperationButtonClick(operation: String) {

    var currentValue: String = textViewCurrentNumber.text.toString()
    var thisOperationNumber: Double = formatStringToDouble(currentValue)

    currentValue = "(${formatDoubleToString(thisOperationNumber)})"

    when (operation) {
        PERCENTAGE -> thisOperationNumber = currentNumber / 100
        ROOT -> thisOperationNumber = thisOperationNumber.sqrt
        SQUARE -> thisOperationNumber *= thisOperationNumber
        FRACTION -> thisOperationNumber = 1 / thisOperationNumber
    }

    if (isInstantOperationButtonClicked) {
        historyInstantOperationText = "($historyInstantOperationText)"
        historyInstantOperationText = StringBuilder().append(operation).append(historyInstantOperationText).toString()
        textViewHistoryText.text = if (isEqualButtonClicked) historyInstantOperationText else StringBuilder().append(historyText).append(currentOperation).append(historyInstantOperationText).toString()
    } else if (isEqualButtonClicked) {
        historyInstantOperationText = StringBuilder().append(operation).append(currentValue).toString()
        textViewHistoryText.text = historyInstantOperationText
    } else {
        historyInstantOperationText = StringBuilder().append(operation).append(currentValue).toString()
        textViewHistoryText.text = StringBuilder().append(historyText).append(currentOperation).append(historyInstantOperationText).toString()
    }

    textViewCurrentNumber.text = formatDoubleToString(thisOperationNumber)

    if (isEqualButtonClicked) currentResult = thisOperationNumber else currentNumber = thisOperationNumber

    isInstantOperationButtonClicked = true
    isFutureOperationButtonClicked = false
}

private fun calculateResult(): String {

    when (currentOperation) {
        INIT -> {
            currentResult = currentNumber
            historyText = StringBuilder().append(textViewHistoryText.text.toString()).toString()
            textViewHistoryText.text = StringBuilder().append(currentResult).toString()
        }
        ADDITION -> currentResult  = currentNumber
        SUBTRACTION -> currentResult -= currentNumber
        MULTIPLICATION -> currentResult *= currentNumber
        DIVISION -> currentResult /= currentNumber
    }

    textViewCurrentNumber.text = formatDoubleToString(currentResult)

    textViewHistoryText.text = StringBuilder().append(textViewHistoryText.text).append(formatDoubleToString(currentNumber)).append(EQUAL)


    if (isInstantOperationButtonClicked) {
        isInstantOperationButtonClicked = false
        if (isEqualButtonClicked) historyText = StringBuilder().append(currentNumber).append(currentOperation).append(formatDoubleToString(currentNumber)).toString()
    } else {
        historyText = StringBuilder().append(historyText).append(currentOperation).append(formatDoubleToString(currentResult)).toString()
    }

    return StringBuilder().append(historyText).append(EQUAL).append(formatDoubleToString(currentResult)).toString()
}

private fun useNumberFormat(): DecimalFormat {

    val symbols = DecimalFormatSymbols()
    symbols.decimalSeparator = '.'

    val format = DecimalFormat("##.####")
    format.decimalFormatSymbols = symbols

    return format
}

private fun formatDoubleToString(number: Double): String {
    return useNumberFormat().format(number)
}

private fun formatStringToDouble(number: String): Double {
    return useNumberFormat().parse(number)!!.toDouble()
}

private val Double.sqrt: Double get() = sqrt(this)

private fun clearEntry(newNumber: Double = 0.0) {
    historyInstantOperationText = ""

    if (isEqualButtonClicked) {
        currentOperation = INIT
        historyText = ""
    }

    if (isInstantOperationButtonClicked) textViewHistoryText.text = StringBuilder().append(historyText).append(currentOperation).toString()

    isInstantOperationButtonClicked = false
    isFutureOperationButtonClicked = false
    isEqualButtonClicked = false

    currentNumber = newNumber
    textViewCurrentNumber.text = formatDoubleToString(newNumber)
}


private fun <T : View> Activity.bind(@IdRes idRes: Int): Lazy<T> {
    return lazy(LazyThreadSafetyMode.NONE) { findViewById<T>(idRes) }
}

}

enter image description here

  • Related