This question already has answers here:
How can I prevent java.lang.NumberFormatException: For input string: "N/A"?
(6 answers)
Closed 2 years ago.
I am using onSavedInstanceState() method so that after after rotating device my textview should not lost its value but i'm getting crash that i've mentioned in activity.
Following is my activity
class SavedInstanceActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_saved_instance)
imgPlus.setOnClickListener {
if (tvText.text.toString().toInt() >= 10)
tvText.text = "10"
else
tvText.text = tvText.text.toString().toInt().plus(1).toString()
}
imgMinus.setOnClickListener {
if (tvText.text.toString().toInt() <= 0)
tvText.text = "0"
else
tvText.text = tvText.text.toString().toInt().minus(1).toString()
}
if (savedInstanceState != null) {
count = savedInstanceState.getInt("int", 0)
tvText.text = count.toString()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("int", tvText.toString().toInt()) //getting crash here java.lang.NumberFormatException: For input string: "com.google.android.material.textview.MaterialTextView{12c8970 V.ED..... ........ 511,982-570,1084 #7f080174 app:id/tvText}"
Log.d("saved", tvText.toString())
}
}
You are tried to convert textview as string instead of text
Try like beklow...
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("int", tvText.text.toString().toInt())
Log.d("saved", tvText.toString())
}
You are using tvText.toString().toInt() it should be tvText.text.toString().toInt() . Also you need to check if text is empty or not before parsing it to Int . See the code below i have made some modifications.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
imgPlus.setOnClickListener {
if (tvText.text.toString().isNotEmpty() && tvText.text.toString().toInt() >= 10)
tvText.text = "10"
else
tvText.text = tvText.text.toString().toInt().plus(1).toString()
}
imgMinus.setOnClickListener {
if (tvText.text.toString().isNotEmpty() && tvText.text.toString().toInt() <= 0)
tvText.text = "0"
else
tvText.text = tvText.text.toString().toInt().minus(1).toString()
}
if (savedInstanceState != null) {
val count = savedInstanceState.getInt("int", 0)
tvText.text = count.toString()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
if(tvText.text.toString().isNotEmpty())
outState.putInt("int", tvText.text.toString().toInt())
}
I don't recommend relying on a text UI element to store your non-text application state. It's kind of convoluted. I would keep the count as an Int property and sync it with the TextView. Actually, I would put the count in the ViewModel if there was one, but for simplicity:
class SavedInstanceActivity : AppCompatActivity() {
private var count = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_saved_instance)
imgPlus.setOnClickListener {
count = min(count + 1, 10)
tvText.text = count.toString()
}
imgMinus.setOnClickListener {
count = max(count - 1, 0)
tvText.text = count.toString()
}
if (savedInstanceState != null) {
count = savedInstanceState.getInt("int", 0)
tvText.text = count.toString()
}
}
//...
}
To take it a step further, you could make the property automatically update the text view when it's changed:
class SavedInstanceActivity : AppCompatActivity() {
private var count by Delegates.observable(0) { _, _, _ ->
tvText.text = count.toString()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_saved_instance)
imgPlus.setOnClickListener {
count = min(count + 1, 10)
}
imgMinus.setOnClickListener {
count = max(count - 1, 0)
}
if (savedInstanceState != null) {
count = savedInstanceState.getInt("int", 0)
}
}
//...
}
As for your specific problem, as the other answers have mentioned, it's because you're trying to convert the text without safely checking if it is parseable as an Int, and it's not if it's blank. It is safer to use toIntOrNull() which gives you an Int? to work with instead of throwing an exception when the text is invalid.
Related
Hey, I have been trying to add decrease function in my android button counter app. There are three buttons(clear, increase, decrease) in my app. Increase is for increasing the counter, decrease is for decreasing the counter and clear is for clearing the textview. i am new here in android. So help me to write the code in kotlin
button?.setOnClickListener(object :View.OnClickListener {
override fun onClick(v: View?) {
numTimeClicked += 1
textview?.append("\n The button got tapped $numTimeClicked time")
if (numTimeClicked != 1){
textview?.append("s")
}
}
})
clear?.setOnClickListener(object :View.OnClickListener{
override fun onClick(v: View?) {
if (numTimeClicked <= 100){
textview?.text = ""
}
}
})
Decrease?.setOnClickListener(object :View.OnClickListener{
override fun onClick(v: View){
if (numTimeClicked >= 1 ){
numTimeClicked -= 1
textview?.append(numTimeClicked.toString())
}
}
})
}
private var userInput:EditText? = null
private var button:Button? = null
private var textview:TextView? = null
private var clear:Button? = null
private var Decrease:Button? = null
private var numTimeClicked = 0
}
fun decreasenumber(var numTimeClicked : Int
) : Int{
numTimeClicked--
return numTimeClicked
}
just replace this line
textview?.append(numTimeClicked.toString())
to
textview?.text = "" + numTimeClicked
append behaves like this: 3 -> 32 -> 321, I think your purpose is to replace not append
I have three activities
MainActivity
StartActivity
EndActivity
When the app loads it opens MainActivty, there are two buttons called Start and End. Clicking on Start takes to StartActivity and End takes to EndActivity. From both these activities, I can swipe back to MainActivity. I want to execute code in MainActivity when the others are swiped away and the MainActivity is revealed.
So far I have tried OnResume and OnRestart events with no success. Please suggest something that I can try?
Please note: I am not interested about the Activity from which I come back from. Only need to execute code when the MainActivity is resumed.
MainActivity
class MainActivity : WearableActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btnStart = findViewById(R.id.btnStartActivity) as Button
btnStart.setOnClickListener{
//Toast.makeText(this#MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
val intent = Intent(this#MainActivity, StartActivity::class.java)
startActivity(intent)
}
val btnEnd = findViewById(R.id.btnEndActivity) as Button
btnEnd.setOnClickListener{
//Toast.makeText(this#MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
val intent = Intent(this#MainActivity, EndActivity::class.java)
startActivity(intent)
}
// Enables Always-on
setAmbientEnabled()
}
fun onRestart(savedInstanceState: Bundle?) {
super.onRestart();
val btnStart = findViewById(R.id.btnStartActivity) as Button
btnStart.text = MyApplication.Companion.g_hour_start.toString() +":" + MyApplication.Companion.g_min_start.toString()
}
}
StartActivity
class StartActivity : WearableActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_start)
val pickerStart = findViewById(R.id.timePickerStart) as TimePicker
pickerStart.setIs24HourView(true)
pickerStart.setHour(MyApplication.Companion.g_hour_start)
pickerStart.setMinute(MyApplication.Companion.g_min_start)
pickerStart.setOnTimeChangedListener(TimePicker.OnTimeChangedListener { view, hourOfDay, minute ->
MyApplication.Companion.g_hour_start = hourOfDay
MyApplication.Companion.g_min_start =minute
})
// Enables Always-on
setAmbientEnabled()
}
override fun onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed()
finish()
}
}
EndActivity is similar to StartActivity
Link to Code: Layout and code
If you launch StartActivity and EndActivity using
startActivityForResult (Intent intent, int requestCode)
you will get a callback once they finish (i.e. dismissed by the user and returns to MainActivity)
onActivityResult (int requestCode, int resultCode, Intent data)
Since you don't care about the activity you come back from you can ignore most of the arguments and just execute the code you need to run.
More details can be found in the official documentation.
I got the code to work. But not sure if it is the right way.
Screen record of the App - TimeDifference Screen Record
MainActivity
class MainActivity : WearableActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//Log.d(TAG,"onCreate: called")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyApplication.Companion.g_hour_start =0
MyApplication.Companion.g_min_start = 0
MyApplication.Companion.g_hour_end =0
MyApplication.Companion.g_min_end = 0
val btnStart = findViewById(R.id.btnStartActivity) as Button
btnStart.setOnClickListener{
//Toast.makeText(this#MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
val intent = Intent(this#MainActivity, StartActivity::class.java)
startActivity(intent)
}
val btnEnd = findViewById(R.id.btnEndActivity) as Button
btnEnd.setOnClickListener{
//Toast.makeText(this#MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
val intent = Intent(this#MainActivity, EndActivity::class.java)
startActivity(intent)
}
// Enables Always-on
setAmbientEnabled()
}
override fun onResume() {
//Log.d(TAG,"onResume: called")
super.onResume();
val btnStart = findViewById(R.id.btnStartActivity) as Button
val btnEnd = findViewById(R.id.btnEndActivity) as Button
val txtCalc = findViewById(R.id.txtResult) as TextView
val StartHour = MyApplication.Companion.g_hour_start
val StartMin = MyApplication.Companion.g_min_start
val EndHour = MyApplication.Companion.g_hour_end
val EndMin = MyApplication.Companion.g_min_end
val DifferenceMinutes : Int
val DiffHour : Int
val DiffMin : Int
if (StartHour + StartMin != 0 ) {
btnStart.text =
StartHour.toString().padStart(2,'0') + ":" + StartMin.toString().padStart(2,'0')
}
if (EndHour + EndMin != 0 ) {
btnEnd.text =
EndHour.toString().padStart(2,'0') + ":" + EndMin.toString().padStart(2,'0')
}
if (StartHour + StartMin != 0 &&
EndHour + EndMin != 0 ){
//txtCalc.textSize = 20f
var TotalStartMinutes = StartHour * 60 + StartMin
var TotalEndMinutes = EndHour * 60 + EndMin
if(TotalEndMinutes> TotalStartMinutes) {
DifferenceMinutes = TotalEndMinutes - TotalStartMinutes
}else{
DifferenceMinutes = TotalStartMinutes - TotalEndMinutes
}
DiffHour = DifferenceMinutes / 60
DiffMin = DifferenceMinutes % 60
if (DiffHour == 0 && DiffMin == 0){
txtCalc.text = "No Difference!!"
}else if (DiffHour == 0){
txtCalc.text = "$DiffMin m"
} else if(DiffMin == 0){
txtCalc.text = "$DiffHour h"
} else{
txtCalc.text = "$DiffHour h and $DiffMin m"
}
}
}
}
StartActivity
class StartActivity : WearableActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_start)
val pickerStart = findViewById(R.id.timePickerStart) as TimePicker
pickerStart.setIs24HourView(true)
pickerStart.setHour(MyApplication.Companion.g_hour_start)
pickerStart.setMinute(MyApplication.Companion.g_min_start)
pickerStart.setOnTimeChangedListener(TimePicker.OnTimeChangedListener { view, hourOfDay, minute ->
MyApplication.Companion.g_hour_start = hourOfDay
MyApplication.Companion.g_min_start =minute
})
// Enables Always-on
setAmbientEnabled()
}
}
For Global Variables
class MyApplication : Application() {
companion object {
var g_hour_start = 0
var g_min_start = 0
var g_hour_end = 0
var g_min_end = 0
}
override fun onCreate() {
super.onCreate()
// initialization code here
}
}
EndActivity is similar to StartActivity
Code and Layout for the WearOS app
My activity has increase btn, decrease btn, productpoint and integer_number for count.
when I clciked decrease btn, integer_number and productpoint changed negative.
So, I dont want get negative.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_details)
var productpoint = findViewById<TextView>(R.id.productPoint)
var point=0
val inc_val=16000
increase.setOnClickListener {
increaseInteger()
point+=inc_val
productpoint.text = point.toString()+"P"}
decrease.setOnClickListener {
decreaseInteger()
point-=inc_val
productpoint.text = point.toString()+"P"
}
fun increaseInteger() {
display(integer_number.text.toString().toInt() + 1)
}
fun decreaseInteger() {
display(integer_number.text.toString().toInt() - 1)
}
private fun display(number: Int) {
integer_number.setText("$number")
}
}
Assume initial value of integer_number TextView is larger than 0, here is my solution.
fun increaseInteger() {
val newValue = integer_number.text.toString().toInt() + 1
if (newValue > 0 && !decrease.isEnabled) {
decrease.isEnabled = true
}
display(newValue)
}
fun decreaseInteger() {
val newValue = integer_number.text.toString().toInt() - 1
if (newValue <= 0) {
decrease.isEnabled = false
}
display(newValue)
}
Try this
fun decreaseInteger() {
if(integer_number.text.toString().toInt()<=0)
{
display(0)
}
display(integer_number.text.toString().toInt() - 1)
}
EditText right drawable doesn't update after showError method gets called. I have tried to set setError to null, set right drawable to null but nothing helps.
Drawable right = DrawableUtils.getDrawable(context,R.drawable.eye_look);
right.setBounds(new Rect(0, 0, rigth.getIntrinsicWidth(), right.getIntrinsicHeight()));
myEditText.setError(null, null);
myEditText.setCompoundDrawablesWithIntrinsicBounds(DrawableUtils.getDrawable(context,R.drawable.pass_look), null, right, null);
Any ideas ?
Code example for checking:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vEditText.error = "Some error"
vButton.setOnClickListener {
vEditText.error = null
}
vEditText.setOnTouchListener(object : OnTouchListener {
override fun onTouch(p0: View?, event: MotionEvent?): Boolean {
val DRAWABLE_LEFT = 0
val DRAWABLE_TOP = 1
val DRAWABLE_RIGHT = 2
val DRAWABLE_BOTTOM = 3
if (event?.action == MotionEvent.ACTION_UP) {
if (event.rawX >= (vEditText.right - vEditText.compoundDrawables[DRAWABLE_RIGHT].bounds.width())) {
vEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(vEditText.context,android.R.drawable.btn_star_big_on), null)
vEditText.error = null
return true
}
}
return false
}
})
}
}
First decorate the EditText with your desired Drawable.
Drawable right = DrawableUtils.getDrawable(context,R.drawable.eye_look);
right.setBounds(new Rect(0, 0, rigth.getIntrinsicWidth(), right.getIntrinsicHeight()));
myEditText.setCompoundDrawablesWithIntrinsicBounds(DrawableUtils.getDrawable(context,R.drawable.pass_look), null, right, null);
...
Now whenever need to show error just use
myEditText.setError("Your error message");
And hide error drawable like below
myEditText.setError(null);
Which actually hide the error drawable and show your drawable. No need to do anything more.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I have update your code, check now
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//This is important to set here
vEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(vEditText.context,android.R.drawable.btn_star_big_on), null)
vEditText.error = "Some error"
vButton.setOnClickListener {
vEditText.error = null
}
}
Now type something on vEditText or click vButton and check.
Try this:
myEditText.setError(null);
myEditText.setErrorEnabled(false);
myEditText.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(context,R.drawable.icon), null, ContextCompat.getDrawable(context,R.drawable.icon), null);
class MainActivity : AppCompatActivity() {
var ind1 = 0;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var im1:ImageView=findViewById(R.id.im1) as ImageView
var im2:ImageView=findViewById(R.id.im2) as ImageView
b1.setOnClickListener()
{
if (ind1 == 0) {
im1.setImageResource(R.drawable.int1)
im2.setImageResource(R.drawable.i1)
}
else if (ind1 == 1) {
im1.setImageResource(R.drawable.int2)
im2.setImageResource(R.drawable.i2)
welcome.text=""
scroll.text = "-=--"
data.text = "Generate Random Teams To Make It More Interesting!"
}
else if (ind1 == 2) {
im1.setImageResource(R.drawable.int3)
im2.setImageResource(R.drawable.i3)
scroll.text = "--=-"
data.text = "Choose From Knockouts,Leagues Or Hybrid Tournaments!"
} else if (ind1 == 3) {
im1.setImageResource(R.drawable.int4)
im2.setImageResource(R.drawable.i4)
scroll.text = "---="
data.text = "Have Fun And Enjoy!!"
b1.text = "LETS GO"
}
ind1++
}
}
}
also tried making an intarrayof and putting the values into that but the app still keeps crashing without giving any error also without the imageviews changing the app works perfectly fine