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) }
}
}