Preserving Value When Orientation Changes - java

I am developing a very basic Android App that adds a number in TextView whenever I hit the Button. The digit showing in TextView is also preserved when the orientation of the Mobile changes using the onSaveInstanceState() and onRestoreInstanceState() functions.
The problem is when orientation changes the value is preserved but when the Button is pressed once again after the changing of the orientation it again starts the counting from 0 rather then starting it from the preserved value.
My code:
public class MainActivity extends AppCompatActivity {
TextView showValue;
int counter=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showValue = (TextView) findViewById(R.id.CounterValue);
}
public void countIN(View view)
{
counter++;
showValue.setText(Integer.toString(counter));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("my_text", showValue.getText().toString());
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
showValue.setText(savedInstanceState.getString("my_text"));
}
}
Thank You for your response.

add
counter=Integer.parseInt(savedInstanceState.getString("my_text"));
inside onRestoreInstanceState method
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
showValue.setText(savedInstanceState.getString("my_text"));
counter=Integer.parseInt(savedInstanceState.getString("my_text"));
}

You can save and get data using several methods
First If your data is small, then you can use onSavedInstanceState and onRestoreInstanceState .. for details follow this answer or this one
Second if you have too much data to store, then use ViewModel instead; this is a tutorial that you can start from.

Related

Increment a variable whenever onCreate() is called

I want to increment the test variable whenever onCreate() is called but my app is crashing. Please help me find out the fix and please tell me why my app is crashing.
public int test = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView num = (TextView) findViewById(R.id.textNum);
new MainActivity().test++;
num.setText(new MainActivity().test);
}
You should never create an instance of Activity by your self
You can directly access your test in your MainActivity no need to use MainActivity().test to access your test variable
if you want to set an integer value to your textview then you need to convert your integer into a string value like String.valueOf(test) or ""+test
Try this way
public int test=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView num=(TextView) findViewById(R.id.textNum);
test++;
num.setText(String.valueOf(test));
}
if you want to increment your test variable whenever onCreate() called then you can use SharedPreferences
SAMPLE CODE
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
public class Main2Activity extends AppCompatActivity {
String prefName = "MY_PREFS_NAME";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
SharedPreferences prefs = getSharedPreferences(prefName, MODE_PRIVATE);
SharedPreferences.Editor editor = getSharedPreferences(prefName, MODE_PRIVATE).edit();
int test = prefs.getInt("counter", 0);
test++;
editor.putInt("counter", test);
editor.apply();
}
}
Okay so let me get you to understand a bit about the activity lifecycle:
onCreate()
Is called every time the activity is created, meaning there is really no use for you to increment the test in this method, because it will always be 1.
onStart()
Will be called every time the activity is shown, meaning when the activity is created or when you go back to the activity, I think this is the method where you increment test.
example
public int test = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView num = (TextView) findViewById(R.id.textNum);
}
#Override
protected void onStart() {
super.onStart();
test++;
num.setText(String.valueOf(test));
}

How to use onSavedInstance?

One quick question:
Why does my onSavedInstance not work? I want to save last state of user activity (current workout session etc.) but in some particular reason it keeps turning me back to the mainActivity when I press the home or overview button and then I return to the application. It should return me the last saved state of activity but something seems to be bugged. I have been struggling with this problem for two weeks. I searched all over the forum but I still can’t find the answer. Hope someone can help:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_workout);
if (savedInstanceState != null) {
// What should I call here?
} else {
// And here?
}
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
onSaveInstanceState(Bundle savedInstanceState) is called when the user leaves your app.It provides a Bundle object that you can pass values you want to save as key value pairs.
static final String WORKOUT_STATE = "state";
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current workout state
savedInstanceState.putInt(WORKOUT_STATE, currentState);
super.onSaveInstanceState(savedInstanceState);
}
There are two options for where you can restore the current state when the activity is recreated. It can be done in onCreate(Bundle savedInstanceState) method or onRestoreInstanceState(Bundle savedInstanceState). If you should do it in onCreate, you should check if the savedInstanceState is not null.
If savedInstanceState is not null then the activity is being recreated and this is where you extract the values.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
currentState = savedInstanceState.getInt(WORKOUT_STATE);
} else {
// Initialize members with default values for a new instance
}
}
Instead of extracting the values in the onCreate method, you can optionally use the onRestoreInstanceState(Bundle savedInstanceState) method. This method is called if there is a state to restore so you don't need to check if savedInstanceState is null.
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore state
currentScore = savedInstanceState.getInt(WORKOUT_STATE);
}
You can read more about saving UI states here: https://developer.android.com/topic/libraries/architecture/saving-states.html
SOLVED!
I fixed my problem,
believe it or not the problem was in FLAG_ACTIVITY_NO_HISTORY in my intent service. Thanks for trying to help!

Setting EditText in Bundle test not working

Hi I am practicing how Bundle savedInstanceState works in Activity creation and it restoration. I have tried this:
private EditText mTextBox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextBox = (EditText) findViewById(R.id.etName);
mTextBox.setText("hello");
if(savedInstanceState != null){
Toast.makeText(this, savedInstanceState.getString("name"),
Toast.LENGTH_SHORT).show();
mTextBox.setText(savedInstanceState.geteString("name"));
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("name", "Joe");
super.onSaveInstanceState(outState);
}
On first onCreate() obviously this will set the EditText field with "hello" as savedInstanceState is null the if block will not be executed. When I change the orientation the Activity goes through all callbacks and Toast the String in the if block, however, it does not set the mTextBox with value from Bundle passed in. The EditText is still set to hello instead of Joe, however, the Toast in if block shows Joe.
Can anyone point out why this is not working as my expectation?
Thanks
This is happening as a result of TextView.getFreezesText, which will:
Return whether this text view is including its entire text contents in
frozen icicles. For EditText it always returns true.
And some more info from TextView.setFreezesText:
Control whether this text view saves its entire text contents when
freezing to an icicle, in addition to dynamic state such as cursor
position. By default this is false, not saving the text. Set to true
if the text in the text view is not being saved somewhere else in
persistent storage (such as in a content provider) so that if the view
is later thawed the user will not lose their data. For EditText it is
always enabled, regardless of the value of the attribute.
icicles is referring to savedInstanceState, that's just what it used to be called.
If you'd like to save and restore the text yourself, you could create a custom EditText and override getFreezesText, something like:
public class NonFreezingEditText extends AppCompatEditText {
public NonFreezingEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean getFreezesText() {
return false;
}
}
You could also use View.post:
mTextBox.post(() -> mTextBox.setText(savedInstanceState.getString("name")));
or Activity.onRestoreInstanceState
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mTextBox.setText(savedInstanceState.getString("name"));
}
You need setText different "hello". see example
private EditText mTextBox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextBox = (EditText) findViewById(R.id.etName);
mTextBox.setText("hello");
if(savedInstanceState != null){
Toast.makeText(this, savedInstanceState.getString("name"),
Toast.LENGTH_SHORT).show();
mTextBox.setText(savedInstanceState.getString("name"));
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
mTextBox.setText("Joe");
outState.putString("name", mTextBox.getText().toString());
super.onSaveInstanceState(outState);
}
OR you must override onRestoreInstanceState. Not call onCreate when text not change.
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if(savedInstanceState != null){
mTextBox.setText(savedInstanceState.getString("name"));
}
}

TextView doesn't show the required text

My MainActivity class has an if that checks is something is true it starts a new Activity which sets the text of a TextView to what I want.
MainActivity:
public static int caseA = 1;
if(caseA) {
Intent i = new Intent(Timer.this, WorkTimerNotification.class);
startActivity(i);
}
then it goes to the new Activity and it should check the value of caseA.
WorkTimerNotification:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work_timer_notification);
TextView timerMetric = (TextView)findViewById(R.id.tester_texter);
if(MainActivity.caseA) {
timerMetric.setText("min");
}
Problem: It does not change the text. Also, lets say I have many other if statements in mainactivity like:
if(caseB) {}
if(caseC) {}
//and so on..
How would I perform the checks? More importantly, how do I get this caseA check to work though.
You need to call findViewById() in onCreate():
private TextView timerMetric;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work_timer_notification);
timerMetric = (TextView)findViewById(R.id.tester_texter);
if(caseA) {
timerMetric.setText("min");
}
}
Right now you are calling it before calling setContentView(), before the view hierarchy is generated. For this reason, your code fails.

whats wrong with this code? it always returns savedInstanceState as null

This code always returns savedInstanceState as null
public class DemoidActivity extends Activity implements OnClickListener, android.view.View.OnClickListener {
EditText t1=null;
EditText t2=null;
EditText t3=null;
EditText t4=null;
String data1 = null,data2=null,data3=null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t1=(EditText)findViewById(R.id.editText1);
t2=(EditText)findViewById(R.id.editText2);
t3=(EditText)findViewById(R.id.editText3);
t4=(EditText)findViewById(R.id.editText4);
Button b1=(Button)findViewById(R.id.button1);
Button b2=(Button)findViewById(R.id.button2);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
}
Their is nothing wrong with the code as such. The reason why you are getting the savedInstanceState as null in your onCreate() method is because your activity is created for the first time and so there won't be any saved state as such.
It will only be set if you implement the method onSaveInstanceState().
http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
It means that your activity's state is never saved.
Try to override the onSaveInstanceState() method:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Put your stuff in the bundle
}
Then use it to retrieve data/activity sate whether in the onCreate() method or in the onRestoreInstanceState() one:
if (savedInstanceState != null) {
//Retrieve data
}

Categories