Setting EditText in Bundle test not working - java

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"));
}
}

Related

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!

Preserving Value When Orientation Changes

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.

OnSaveInstanceState and OnRestoreInstanceState not saving on app quit

I am trying to save my programmatically created CardView and TextView using OnSaveInstanceState and OnRestoreInstanceState as in the sample code.
While debugging, I notice that values are saved but when I quit the app and reopen it, nothing is being restored.
What am I doing wrong?
**#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("key", userInput.getText().toString());
savedInstanceState.putInt("LayoutId", mConstraintLayout.getId());
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getString("key");
savedInstanceState.getInt("LayoutId");
}**
This are the methods I am using after 'OnCreate'
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = getApplicationContext();
mConstraintLayout = findViewById(R.id.top_left);
addButton = findViewById(R.id.add);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View popup = findViewById(R.id.popup);
popup.setVisibility(View.VISIBLE);
}
});
mButton = (Button) findViewById(R.id.create);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final CardView sticker = new CardView(mContext);
CardView.LayoutParams params = new CardView.LayoutParams(
CardView.LayoutParams.WRAP_CONTENT,
CardView.LayoutParams.WRAP_CONTENT
);
params.height=500;
params.width=500;
CheckBox privateCalendar = findViewById(R.id.checkPrivate);
CheckBox workCalendar = findViewById(R.id.checkWork);
CheckBox holidayCalendar = findViewById(R.id.checkHoliday);
if (privateCalendar.isChecked()){
sticker.setCardBackgroundColor(Color.parseColor("#FFCC00"));
}
else if (workCalendar.isChecked()){
sticker.setCardBackgroundColor(Color.parseColor("#FF8080"));
}
else if (holidayCalendar.isChecked()){
sticker.setCardBackgroundColor(Color.parseColor("#66B3FF"));
}
else{
sticker.setCardBackgroundColor(Color.parseColor("#FFCC00"));
}
sticker.setId(CardView.generateViewId());
sticker.getId();
sticker.setTag(CARD_VIEW_TAG);
sticker.setLayoutParams(params);
sticker.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
ClipData.Item item = new ClipData.Item((CharSequence) sticker.getTag());
String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData data = new ClipData(sticker.getTag().toString(), mimeTypes, item);
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(sticker);
sticker.startDrag(data
, shadowBuilder
, sticker
, 0
);
sticker.setVisibility(View.INVISIBLE);
return true;
}
});
TextView tv = new TextView(mContext);
tv.setLayoutParams(params);
tv.setBackgroundColor(Color.TRANSPARENT);
tv.setGravity(Gravity.CENTER);
userInput = findViewById(R.id.editText);
tv.setText(userInput.getText());
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
tv.setTextColor(Color.BLACK);
sticker.addView(tv);
mConstraintLayout.addView(sticker);
View popup = findViewById(R.id.popup);
popup.setVisibility(View.GONE);
}
});
}
SavedInstanceState and RestoreInstanceState will work if activity is recreated due to config change like orientation change or android system killed that activity due to memory issue, Then only savedInstanceState and restoreInstanceState comes in role.
If you finish activity by yourself and start activity again then there is no use of these methods.
Try to save data in SharedPreference instead savedInstanceState.
SharedPreferences pref =
getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
For Storing data:-
editor.putString("key", userInput.getText().toString());
editor.putInt("LayoutId", mConstraintLayout.getId());
editor.apply();
For retriving data:-
editor.getString("key", null); // getting String
editor.getInt("LayoutId", 0); // getting Integer
First of all if by "close the app" you mean destroy it, this will never work for you.
Second of all in onRestoreInstanceState you don't do anything with those values, you simply read them but don't store them anywhere.
If you mean to recreate the old form after switching back and forth between apps, with your app being destroyed in the background then, you need to only set values in onSaveInstanceState like you did, and in onCreate(Bundle savedInstance), you should do something like this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstance == null) {
//read values from getIntent()
key = getIntent().getString("key);
LayoutId = getIntent().getInt("LayoutId");
} else {
//read values from savedInstanceState
key = savedInstanceState.getString("key");
LayoutId = savedInstanceState.getInt("LayoutId");
}
}

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