0

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())
    }
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Well the text in `tvText` is not parsable to Int, can you paste what is the text in `tvText` – rahat Jan 12 '21 at 05:02
  • you need to write tvText.getText().toString().toInt() because getText() will pass the value from tvText otherwise as per your code tvText's id string will be given to you as output – PJain Jan 12 '21 at 06:13

3 Answers3

0

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())
}
Rajasekaran M
  • 2,478
  • 2
  • 20
  • 30
0

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())
}
ADM
  • 20,406
  • 11
  • 52
  • 83
0

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.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154