So I'm trying to learn Kotlin and i'm a few days in. I am trying to build a Coin Calculator app that will take input of quantity of each type of coin you have and then using a class value it will add up all your change and tell you a total. I apologize for not being able to be too specific other than my error: None of the following functions can be called with the arguments supplied:
public final operator fun times(other: Byte): Double defined in kotlin.Double
public final operator fun times(other: Double): Double defined in kotlin.Double
it's showing these on my quarter total and dime total variables.
As I said I am new and actively studying looking for insight on what I am doing wrong, also any other advice over my messy coding that you see would be greatly appreciated.
-Thanks!
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//MyCode
val submitButton: Button = findViewById(R.id.submit)
var quarterQuan: EditText = findViewById(R.id.quarterInput)
var dimeQuan: EditText = findViewById(R.id.dimeInput)
submitButton.setOnClickListener{
val dime = Dime()
val quarter= Quarter()
var quarterTotal: Float = quarter.quarterVal*quarterQuan
var dimeTotal: Float = dime.dimeVal*dimeQuan
var cashTotal: Float = dimeTotal + quarterTotal
val resultTextViewLabel: TextView = findViewById(R.id.textResult)
resultTextViewLabel.text = cashTotal.toString()
}
}
}
class Quarter(){
val quarterVal = 0.25
}
class Dime(){
val dimeVal = 0.10
}
quarterQuan and dimeQuan are of type EditText (they are not numbers) and cannot be multiplied with a Float.
What you need to do is to read the values of these EditTexts:
val quarterEditTextValue = quarterQuan.text.toString().toFloat()
val dimeEditTextValue = dimeQuan.text.toString().toFloat()
You can then use these values for multiplication
var quarterTotal = quarter.quarterVal*quarterEditTextValue
var dimeTotal = dime.dimeVal*dimeEditTextValue
Have to add that you need to make each initial EditText value to be 0.0 to avoid NumberFormatException.
<EditText
android:id="#+id/quarterInput"
android:text="0.0" .... />
Related
I'm doing tests in android studio for a tutorial and the test results show me this:
expected:<2,00[ ]$> but was:<2,00[ ]$>
Expected :2,00 $
Actual :2,00 $
I'm a bit confused ! both are the same string....
EDIT:
This is the method i'm testing
#VisibleForTesting
internal fun calculateTip(
amount: Double, percent: Double = 15.0, roundUp: Boolean): String{
var tip = percent / 100 * amount
if (roundUp)
tip = kotlin.math.ceil(tip)
return NumberFormat.getCurrencyInstance().format(tip)
}
This is the test assertion:
#Test
fun calculate_20_percent_tip_no_roundup() {
val amount = 10.00
val tipPercent = 20.00
val expectedTip = "2,00 $"
val actualTip = calculateTip(amount = amount, percent = tipPercent, false)
assertEquals(expectedTip, actualTip)
}
Adding this to shed light on the difference...
In order to recreate I had to use the locale
java.text.NumberFormat.getCurrencyInstance( Locale("fr", "CA" )).format(2.00)
In the run log for the test it will show:
And if you click on Click to see difference it shows:
So the NumberFormat for that particular locale currency introduces the NBSP. Unfortunately cannot explain why it would do that.
MFP:
#Test
fun test_currencyComparison() {
val expected = "2,00 $"
val actual = java.text.NumberFormat.getCurrencyInstance( Locale("fr", "CA" )).format(2.00)
println("$expected $actual")
assertEquals(expected, actual)
}
One way to overcome this in your case would be to use the same NumberFormat to generate the expected:
#Test
fun calculate_20_percent_tip_no_roundup() {
val amount = 10.00
val tipPercent = 20.00
val expectedTip = java.text.NumberFormat.getCurrencyInstance().format(2.00)
val actualTip = calculateTip(amount = amount, percent = tipPercent, false)
assertEquals(expectedTip, actualTip)
}
I am getting some kind of empty string Amount function but dont know as im passing not null and non empty string
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editText: EditText = findViewById(R.id.cost_of_service)
val radioGroup: RadioGroup = findViewById(R.id.tip_options)
val cal: Button = findViewById(R.id.calculate_button)
val message: String = editText.text.toString()
val tv: TextView = findViewById(R.id.tip_result)
getSignal(radioGroup, cal, message, tv)
}
private fun getSignal(radioGroup: RadioGroup, cal: Button, message: String, tv: TextView){
cal.setOnClickListener{
val selectedRB: RadioButton = findViewById(radioGroup!!.checkedRadioButtonId) //selectedRB -> selected radio button id
val per: String = selectedRB.text.toString()
val amount: Double = Amount(per, message)
tv.text = amount.toString()
}
}
private fun Amount(per: String, message: String): Double {
return message.toDouble() + (message.toInt() * per.toInt()) / 100
}
val message: String = editText.text.toString()
That gets the value of the editText at the time its called. It does not update it as it changes. Since you're calling this in onCreate, its almost certainly empty. And since it's empty, its not a numbver so trying to convert it to one fails.
The fix for this is to put this inside your onClickListener. Do the same for every field you want to get the text out of.
I have a TextEdit that has the input type of numberDecimal and I executes some code with inputted number
when I enter a whole number it works fine but when I enter a number with a decimal point the app completely restarts
So how would I make it work with a decimal number?
if you do end up helping me thank you in advanced
KT file
class f_to_c : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.f_to_c)
val actionBar = supportActionBar
val calculate = findViewById<Button>(R.id.calculate)
val tempEntered = findViewById<TextView>(R.id.tempEntered)
val result = findViewById<TextView>(R.id.result)
val temp = findViewById<EditText>(R.id.temp)
if (actionBar != null){
actionBar.title = "Fahrenheit To Celsius"
actionBar.setDisplayHomeAsUpEnabled(true)
}
calculate.setOnClickListener {
var x = Integer.parseInt(temp.getText().toString()).toString().toInt()
tempEntered.text = x.toDouble().toString()
result.text = ((x-32).toFloat()*5/9).toString()
}
}
}
If you want to handle decimal numbers, you shouldn't use Integer.parseInt. That will throw an error on something like "1.23". The following should work (or you could use Double.parseDouble)
val x = temp.getText().toString().toDoubleOrNull() ?: 0.0
tempEntered.text = x.toString()
result.text = ((x-32.0)*5.0/9.0).toString()
You may want to handle the null case differently in case the user enters an invalid number like "1..3", but this would just default to 0 in that case instead of throwing.
Also, if this is to be used internationally, you should consider that some locales use a comma for a decimal separator ("1,23") - which will break here. You could either use a locale-aware number parser for that, or just replace commas with periods before converting.
val xs = temp.getText().toString().replace(",",".")
val x = xs.toDoubleOrNull() ?: 0.0
package com.example.tipcalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import kotlin.text.toFloat as kotlinTextToFloat
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.hide()
val tenPerTip: Button = findViewById(R.id.tenPerTipButton)
val fifteenPerTip: Button = findViewById(R.id.fifteenPerTipButton)
val twentyPerTip: Button = findViewById(R.id.twentyPerTipButton)
val customTip: Button = findViewById(R.id.customTipSubmit)
val sumRaw: EditText = findViewById(R.id.billEnter)
val tipOnlyResult: TextView = findViewById(R.id.tipOnlyResult)
val totalResult: TextView = findViewById(R.id.totalResult)
val sumString = sumRaw.toString()
val sumInput = sumString.toInt()
tenPerTip.setOnClickListener{
val sumTotal = sumInput * 1.1
val tipOnly = sumInput * 0.1
tipOnlyResult.text = tipOnly.toString()
totalResult.text = sumTotal.toString()
}
fifteenPerTip.setOnClickListener{
}
twentyPerTip.setOnClickListener{
}
customTip.setOnClickListener{
}
}
}
I was trying to switch the EditText input to a string and from there to a float so that I can do calculations on it. On the line with val sumInput = sumString.toInt() the code breaks. It will compile, but when I try to run an emulator it casts error codes about the toInt declaration. The code is using toInt in this because I was trying to see if the emulator would like that. Also whenever I declare that toInt it highlights in a light yellow italic font, which I haven't seen before.
I have Edited your code.
Changes to the code is explained with the comments below.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.hide()
val tenPerTip: Button = findViewById(R.id.tenPerTipButton)
val fifteenPerTip: Button = findViewById(R.id.fifteenPerTipButton)
val twentyPerTip: Button = findViewById(R.id.twentyPerTipButton)
val customTip: Button = findViewById(R.id.customTipSubmit)
val sumRaw: EditText = findViewById(R.id.billEnter)
val tipOnlyResult: TextView = findViewById(R.id.tipOnlyResult)
val totalResult: TextView = findViewById(R.id.totalResult)
/** if you put sumString and sumInput here, what happens is when your app
* is created and the onCreate method is called sumString is initialized
* here without using .text, i.e., sumRaw.text command what happens is sumString
* will be initialized with sumRaw value (i guess maybe sumRaw id) and you will
* get error.
* Also, this is only called once when all the other variable are initialized.
* If you want to use it outside use a TextWatcher and change the variable as
* soon as it is updated in the EditText.
* A work-around would be initializing this value inside OnClickListener, what
* happens here is whenever you click tenPerTip Button sumString is Initialized
* with current values in sumRaw EditText.
*
* Do use .text else it will give errors.
*/
tenPerTip.setOnClickListener {
val sumString = sumRaw.text.toString()
// what happens here is sumString is converted to Double if it has valid pattern
// else it will return null
// And then the elvis operator will check for null. If its null, it will not
// not proceed further and will get out the listener.
val sumInput = sumString.toDoubleOrNull() ?: return#setOnClickListener
val sumTotal = sumInput * 1.1
val tipOnly = sumInput * 0.1
tipOnlyResult.text = tipOnly.toString()
totalResult.text = sumTotal.toString()
}
fifteenPerTip.setOnClickListener {
}
twentyPerTip.setOnClickListener {
}
customTip.setOnClickListener {
}
}
}
You seem to think the that when you write val sumString = sumRaw.toString(), it gives you the text entered in R.id.billEnter which is not correct. to get text from an EditText you have to use text property. As for your code it can be fixed as
tenPerTip.setOnClickListener{
val sumString = sumRaw.text.toString()
val sumInput = sumString.toInt()
val sumTotal = sumInput * 1.1
val tipOnly = sumInput * 0.1
tipOnlyResult.text = tipOnly.toString()
totalResult.text = sumTotal.toString()
}
I have SecondActitivity and when it starts I assign specific values: listTitle, dbJustForPlaing,currentCursorPosition, numberA and so on.
class SecondActivity : OptionMenuHelper() {
val listTitle: String by lazy { intent.getStringExtra(Values.listTitle) }
lateinit var dbJustForPlaing: DataBaseJustForPlaying
var currentCursorPosition: Int = -1
lateinit var cursorOfWholeList: Cursor
var lastCursorPosition: Int = -1
lateinit var oneRowCursor: Cursor
var numberA = 0
var numberB = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_personal_test)
//some functions
}
}
During the use of this activity, variables are changing. Now I want to add button to SecondActivity, if user presses it, all variables must be returned to same state like they were when activity just started. What is the best way to do that?
I can do this:
fun startNewActitivy(){
val intent = Intent(this, SecondActitivity::class.java)
intent.putExtra("listTitle", listTitle)
startActivity(intent)
finish
}
But I am not sure if this is correct way to do. I need piece of code which will help to easy support my app in future and which also will be efficient in device resource consumption
As pointed out by Peyman in the comments, just create a function that set's the default values for the variables. Something along the following lines,
fun setVariableDefaultValues() {
currentCursorPosition = -1
lastCursorPosition = -1
numberA = 0
numberB = 0
}
You can then call the setVariableDefaultValues() method anywhere you want to reset the values.