Currency NumberFormat change the `format` behaviour after calling `parse` - android

I create a numberFormat to not return strings with decimals like:
val numberFormat = NumberFormat.getCurrencyInstance().apply {
minimumFractionDigits = 0
}
1. If I call format it returns fine
numberFormat.format(123) // "$123"
2. If I call parse with other value
numberFormat.parse("$333") // a number -> 333
3. And call format again with 123, the returned value contains the decimals! the format changed!.
numberFormat.format(123) // "$123.00"
Why? What can we do so it returns always with format without decimals like 1.?
I made a repo to reproduce it: https://github.com/danielgomezrico/test-numericformat-format-parse-error-sample.
It looks like it only fails on android not in java.
Take a look to MainActivity.kt

Never used NumberFormat so I am not sure why it acts like that... but one work around would be to make your numberFormat a class variable with a custom getter like so:
val numberFormat: NumberFormat
get() = NumberFormat.getCurrencyInstance().apply { maximumFractionDigits = 0 }
and then when you access it this way, it will apply the maximumFractionDigits each time

Related

How to add decimal values to entries for chart using MpAndroidChart Library?

I'm trying to create a line chart in Android using MPAndroidChart Library and as entries I have values like 1200.10, 1300.70 and so on, but on my chart the values are rounded (1200, 1301), and I want to display the original values. How can I do that? I tried different solutions but couldn't solve the problem yet. I'm using the Kotlin language. Thanks!
for (item in reversedCashList) {
if (i <= daysNmb) {
var cashValue: String = transformDataForChart(item.value!!)
dataValsEntries.add(Entry(i, cashValue.toFloat()))
i++
}
}
Also, I'm using this formatter Class to format my values because the initial format is like 120.200,10 and I changed them to 120200.10 but this values is displayed as 120200. My Formatter Class:
private fun transformDataForChart(totalValue: String): String {
return if (totalValue.contains(".")) {
val test = totalValue.replace(".", "")
test.replace(",", ".")
} else {
totalValue.replace(",", ".")
}
}
You can try with BigDecimal, something like BigDecimal.valueOf(X).setScale(decimalPlace(usually 2), BigDecimal.ROUND_HALF_UP).floatValue()
The idea is that float cannot hold so many values as the Double, I've encountered this issue as some point as well, and I had to change everything to Double just to make it more easier to maintain... Therefor I don't think is a straight-forward method to keep everything you need in the float format.

Android Studio Kotlin - How to display 2 digit number in text?

On creating a timer In Android Studio Kotlin.
I'd like to display the time value as it's 2 digit number like '01:04:07'.
Please see the below.
At this point, how do I change the code?
Simply use String.format() like:
timerDisplay.text = String.format("%02d:%02d:%02d", lapsHours, lapsMinutes, lapsSeconds)
You can use DecimalFormat as below:
val f: NumberFormat = DecimalFormat("00")
timerDisplay.text = "${f.format(lapshours)}:${f.format(lapsMin)}:${f.format(lapsSec)}"
You can use your extension function on Int like
fun Int.format(): String{
return if(this<10 && this>=0) "0"+this.toString() else this.toString()
}
simple call format() function on your Int variable to get your required format.
timerDisplay.text = "${lapsHours.format()} : ${lapsMinutes.format()} : ${lapsSeconds.format()}"

Kotlin: SumbyDouble returning additional decimals

I am summing double value from arraylist its giving additional decimals as 99999, how to fix this, please guide
ex
class ExDet{var expName:String ="",var expAmount:Double = 0.0}
val arrayList = ArrayList<ExDet>()
arrayList.add(ExDet("Abc 1",45.66))
arrayList.add(ExDet("DEF 1",10.0))
arrayList.add(ExDet("Lee 1",600.89))
arrayList.add(ExDet("Ifr 1",200.9))
var amt = arrayList.sumByDouble{ it.expAmount }
Expected Value of Amount is :
Amt = 857.45
But it returns
Amt = 857.4499999
Sample Code to Test
data class ExDet(var expName:String ="" ,var expAmount:Double=0.0)
fun main(args: Array<String>) {
val arrayList = ArrayList<ExDet>()
arrayList.add(ExDet("Abc 1",45.66))
arrayList.add(ExDet("DEF 1",10.0))
arrayList.add(ExDet("Lee 1",600.89))
arrayList.add(ExDet("Ifr 1",200.9))
var amt = arrayList.sumByDouble{ it.expAmount }
println("Amount is : $amt")
}
The issue you are confronted with is that floating point numbers are build on top of base 2, not base 10.
Think how you can easily represent a third as a fraction (1/3), but when you convert to decimal you get a repeating (recurring) number after the radix point (i.e. 0.33...). Some decimal numbers are recurring when represented in base-2, e.g. x.9. The computer has a finite number of bits, so the (base-2) number is truncated. All the truncation errors can add up.
You need to round to the required precision (e.g. round(x * 100) / 100).
If you are only interested in how it is displayed then you can use the format function with something like "%.2f".
String.format("%.2f", value)

How to append 2 strings in Kotlin?

I am trying to concatenate 2 String but not sure how to go about it.
this is my code:
val word = R.string.word
and i'm trying to append it with "$currentPage/5" inside the setText("$currentPage/5")
i tried to make it in this way setText("$word $currentPage/5")
and this way setText("${R.string.value} $currentPage/5")
and it did not work , it only shows me numbers not the text
try to use this:
val word = getString(R.string.word)
text_view.text = "$word $currentPage/5"
If you want to edit your value (e.g. current page) wrap it with {}
E.g.
val word = getString(R.string.word)
text_view.text = "$word ${currentPage/5}"
Remember to use proper kotlin syntax
In Kotlin, the concatenation of string can be done by **interpolation/templates**.
val a = "Its"
val b = "Kotlin!"
val c = "$a $b"
The output will be Its Kotlin!
Or we can alson do concatenate using the **+ / plus() operator**:
val a = "String"
val b = "Concatenate"
val c = a + b
val d =a.plus(b)
print(c)
The output will be: StringConcatenate
print(d)
The output will be: StringConcatenate
Or you can concatenate using the StringBuilder which is a normal way to do that.
To concatenate two string, we could do
val concatenatedWord = "${resources.getString(R.string.value)}:
${number/3}."
If R.string.value was "The result" and number was 15, value of concatenatedWord will be "The result: 5."
Or we could also concatenate using the + operator or using StringBuilder.
But if you do
textView.text = "${resources.getString(R.string.value)}: ${number/3}."
AS will warn "Do not concatenate text displayed with setText." so, in the case of setting concatenated text in textview, consider using
String.format("%s: %d.", resources.getString(R.string.value):
number/3)
As a future resource and answer why the accepted answer works:-
String Templates:-
Strings may contain template expressions, i.e. pieces of code that are evaluated and whose results are concatenated into the string.
How to implement these?
A template expression should start with a dollar sign ($) and consists of either a simple name:
when the expression is a simple variable.
val i = 10
println("i = $i") // prints "i = 10"
or else arbitrary expression in curly braces:
val s = "abc"
println("$s.length is ${s.length}") // prints "abc.length is 3"
Note :- Templates are supported both inside raw strings and inside escaped strings.
val nameOfAnimal = "fish"
val speciesClass = "is an Aquatic Vertebrate"
println(nameOfAnimal.plus(speciesClass))
println(nameOfAnimal+speciesClass)
println("$nameOfAnimal $speciesClass")
Results:
fishis an Aquatic Vertebrate
fishis an Aquatic Vertebrate
fish is an Aquatic Vertebrate

How do I set the text of an EditText to an Int?

In an attempt to set an EditText to an Int value, I've tried various ways of converting the Int to a value that the EditText will accept, but all fail:
processButton.setOnClickListener {
var intNo = inputText.text as Int
intNo *= 2
outputText.text = intNo as String // error = "required editable"
outputText.text = intNo.toString() // err: type mismatch
outputText.text = Int.toString(intNo) // type mismatch reqd editable
outputText.text = "What is going on?" // type mismatch reqd editable
}
How can I set the EditText to an Int value?
var a: Int = 12
var s: String = a.toString()
This should work for this.
Try given code it will work. What I am doing here I am converting inputText first to String then Int. After I am multiplying with 2 then I am assigning a value for outputText by converting to string.
processButton.setOnClickListener {
var intNo = inputText.text.toString().toInt()
intNo *= 2
//println(intNo.toString())
val myString = intNo.toString()
// If you using outputText as Editable then use this
outputText.text = SpannableStringBuilder(myString)
}
There are a couple things going on here, and to understand them, let's take a look at the various getText and setText methods that EditText has:
Editable getText()
void setText(CharSequence text)
void setText(#StringRes int resid)
// many other setText methods with buffer options
So what Kotlin does here to let you use property syntax is that it creates a text property. The getter used for the property is obvious, since there's only one. The setter for the property is supposed to be the one that takes a CharSequence parameter (it would make sense, Editable extends CharSequence), but actually trying to assign anything other than an Editable to it won't work. See this issue.
To get to the problem at hand, you can read the value in your EditText and convert it to a String like this:
val input = inputText.text.toString()
Then, you can use the toInt() function from the standard library to convert it to an Int (be aware that this will throw an exception if the String can't be parsed):
val doubled = input.toInt() * 2
And finally, you can set the value of the EditText by calling the setText setter in the traditional Java style, passing in a String:
inputText.text.setText(doubled.toString())
A bit of a mess because of the two-way conversion between String and Int, plus the oddities of how the text property is generated here, but that's the way to do it. If you're bothered by how this looks, you could always hide some of this mechanism behind extension properties.
var num: Int = 5
to convert to string would be
num.toString()

Categories

Resources