How to input a decimal number in a textEdit - android

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

Related

Formating a string from right to left for currency values

I'm working on creating a way to input an amount and format it from left to right with placeholder zeros.
For example, pressing 1 and 2 would show $0.12 pressing 3 would give $1.23. Pressing backspace would give $0.12.
Instead, I am getting $1,0002.00
binding.keypad.btnBackspace.setOnClickListener {
val text = binding.tvTotalValue.text.toString()
if(text.isNotEmpty()) {
binding.tvTotalValue.text = text.drop(1)
}
binding.tvTotalValue.text = ""
}
binding.keypad.onNumberSelected = {
processNewAmount(it.toString())
}
private fun processNewAmount(newValue: String) {
val text = binding.tvTotalValue.text.toString().plus(newValue)
val result = text.replace("[^0-9]".toRegex(), "") // remove any characters
val amount = result.toDouble()
binding.tvTotalValue.text = NumberFormat.getCurrencyInstance().format(amount)
}
What am I doing wrong?
Is there a better way to do this?
I advise keeping a property that stores the entered value without formatting. Each time a number is added, you can add it to this entered number and then format it for the screen. That will be a lot simpler than trying to move/remove existing symbols around in the String.
private var enteredNumber = ""
//...
binding.keypad.btnBackspace.setOnClickListener {
enteredNumber = enteredNumber.dropLast(1)
refreshTotal()
}
binding.keypad.onNumberSelected = {
if(!(it == 0 && enteredNumber == "0")) { // avoid multiple zeros or backspace will act unexpectedly
enteredNumber += it.toString()
refreshTotal()
}
}
//...
private fun refreshTotal() {
val amount = enteredNumber.toDouble() / 100.0
binding.tvTotalValue.text =
NumberFormat.getCurrencyInstance().format(amount)
}

split string between 2 char based index

How can we split a text between two char in Kotlin?
Example string:
base_id:94, user_id: 320903, is_Active=1
I want to get only user_id so "320903". But I couldn't do that.
One way to get it is using regex and you can customize it to cover base_id and is_Active
val pattern = Pattern.compile("user_id: (?<id>[0-9]+)")
val matcher = pattern.matcher(text)
if (matcher.find()) {
val group = matcher.group("id").trim()
println(group)
}
The output will be : 320903
Or you can do that with split only and you will get the same result
val items = text.split(",")
val userId = items[1].split(":")[1].trim()
println(userId)
That will work correctly with your example but make sure but for other cases, you may need to customize it or give us many examples to cover them
You can handle the 3 values with one function that support optional whitespace and : or =
fun getValueByTagName(text : String, tag : String) : String {
val pattern = Pattern.compile("$tag[:=][ ]*(?<id>[0-9]+)")
val matcher = pattern.matcher(text)
return if (matcher.find())
matcher.group("id").trim()
else ""
}
To use it
println(getValueByTagName(text, "base_id")) // 94
println(getValueByTagName(text, "user_id")) // 320903
println(getValueByTagName(text, "is_Active")) // 1
Another solution:
Method 1: If your string has exactly the same format that you have shown in the example.
val indexOfUserId = s.indexOf("user_id") // find index of the substring "user_id"
val end = s.indexOf(',', indexOfUserId) // find index of ',' after user_id
val userId s.substring(indexOfUserId + 9, end) // take the substring assuming that userId starts exactly 9 characters after the "u" in "user_id"
Method 2: If your format can vary (in spaces and symbols). Also assuming that user_id is always a number.
val indexOfUserId = s.indexOf("user_id")
val start = s.findAnyOf(List(10) { "$it" }, indexOfUserId)!!.first // find the first digit after "user_id"
val userId = s.substring(start).takeWhile { it.isDigit() } // start from the first digit and continue as long as you are getting digits
Here, List(10) { "$it" } is just a list of all digits in string format and findAnyOf:
Finds the first occurrence of any of the specified [strings] in this char sequence, starting from the specified [startIndex]
Try it yourself

How do I get a text input from a dynamically selected text input box in Android using Kotlin?

I have a multiple TextInput named input_x where x is a number (e.g input_1, input_2 etc.,). I also have multiple buttons named btn_x where x is a number (e.g btn_1, btn_2 etc.,).
When a btn_x is pressed, I should be able to print the value of the input that has matches the x value (e.g when btn_2 is pressed, value inside input_2 will be printed.)
This is my current attempt that does not work:
fun handleClickButton (view: View) {
with (view as Button) {
var this_btn = view.resources.getResourceEntryName(id)
val id_string = this_btn
val delim = "_"
val arr = id_string.split(delim).toTypedArray()
val id_num = arr[2]
val this_input = "input_" + arr[2].toString()
print(binding.this_input.text)
}
}
Any help would be really really appreciated! I am very new to android development and Kotlin.
Here are the issues that need to fix:
Getting arr[2] while the length of the arr is 2; So this should be arr[1] as arrays are 0-baed indices to avoid ArrayIndexOutOfBoundsException
A text value is invoked on the binding object with this expression binding.this_input and binding requires to have a view id:
Not sure if you can use view bindings for an int as view ID, because this reference name of that view is not registered in the generated binding class.
But at least you can achieve that with findViewById:
Applying that in your code:
fun handleClickButton(view: View) {
with(view as Button) {
val this_btn = view.resources.getResourceEntryName(id)
val id_string = this_btn
val delim = "_"
val arr = id_string.split(delim).toTypedArray()
val id_num = arr[1]
val this_input = "input_" + arr[1]
val id = resources.getIdentifier(this_input, "id", context.packageName)
val input = this#MainActivity.findViewById<EditText>(id)
print(input.text)
}
}
Note: I'm assuming the surrounding activity as MainActivity, you can replace it with your activity as omitting it will get findViewById() called on the button.

Kotlin parse double from string

In Kotlin how to parse a double or float number from string like this:
var st: String? = "90 min"
tried to use toDoubleOrNull but always returns 0 or null.
If you are certain that the number is always at the start, then use split() with space as delimiter and from the returned list take the 1st item and parse it to Double:
val value = st!!.split(" ")[0].toDoubleOrNull()
If there is a case of spaces at the start or in between, use this:
val value = st!!.trim().split("\\s+".toRegex())[0].toDoubleOrNull()
And another way with substringBefore():
val value = st!!.trim().substringBefore(" ").toDoubleOrNull()
Or if there is only 1 integer number in the string, remove every non numeric char with replace():
val value = st!!.replace("\\D".toRegex(), "").toDoubleOrNull()
You can try (assuming you have only one sequence of numbers in your string).
Otherwise, check other answers
val inputString = "123. Test"
val regex = "\\d+(\\.\\d+)?".toRegex()
val match = regex.find(inputString)
if (match != null) {
println("Result: " + match.value)
} else {
println("Result: Not found")
}
This should work...
val pattern = Pattern.compile("\\d+") // the regex
val matcher = pattern.matcher("hello123hgj") // your string
val doubles = ArrayList<Double>() // results
while (matcher.find())
{ // for each match
doubles.add(Double.parseDouble(matcher.group())) // convert to double
}
It depends on what you need. If you just have to get 90 and the string is formatted always in the same way you can just
var string = "90 min"
var floatFromString = string.substring(0,2).toFloat()
but it's better to learn how to use LocalDate and DateTimeFormatter

Kotlin Android Studio Warning "Do not concatenate text displayed with setText. Use resource string with placeholders."

I made a simple program to learn about concatenation in android studio with Kotlin. So, I tried to get a string value from resources in strings.xml as shown below and concatenate with a value
<string name="txt_show">Your lucky number is %1$s</string>
I got warning "Do not concatenate text..." from getString
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val firstNumber = numEditText.text
processButton.setOnClickListener {
val result = concatText(firstNumber.toString().toDouble())
resultView.text = getString(R.string.txt_show, " ") + result.format(2)
}
}
private fun concatText(myNumber: Double): Double {
val luckyNumber = 1.79
return luckyNumber * myNumber
}
private fun Double.format(digits: Int) = java.lang.String.format("%.${digits}f", this)}
By replacing
resultView.text = getString(R.string.txt.show, " ") + result.format(2)
with
val finalResult = result.toInt()<p>
resultView.text = getString(R.string.txt_show, finalResult)<p>
And replace %1$s to %1$d in resources of strings.xml
The warning is gone but I got problems, first the result is integer which is not what I expected. It should be double. Second, adding the function format in getString will stop the program with "Unexpected Error..." message on the screen.
How can I solve this problem?
If you have string with some placeholders like:
<string name="price_string">Your price: %d</string>
First you have to read this value and next fill it
JAVA
String text = getString(R.string.price_string, 2.5);
KOTLIN
val text = getString(R.string.price_string, 2.5)
.
or in "longer" way:
JAVA:
// Read text
String priceString = getString(R.string.price_string);
// Fill it
String output = String.format(priceString, 2.5);
KOTLIN
// Read text
val priceString = getString(R.string.price_string)
// Fill it
val output = String.format(priceString, 2.5)
// or
val output = priceString.format(2.5)
If you have %s you have to fill it with String. Here you have more info: https://developer.android.com/guide/topics/resources/string-resource#formatting-strings
first the result is integer which is not what I expected. It should be double.
Then why did you call toInt? Just use
resultView.text = getString(R.string.txt_show, result)
and %1$.2f (or just %.2f) in the string instead of %1$d to format to two digits fractional number. You can see it's specified the same as in the format function in your code. The documentation for format strings (what all of these %d etc. mean) is at https://developer.android.com/reference/java/util/Formatter.html.

Categories

Resources