Is there any simple way to save the whole activity instance and restoring it ?
After spending 1 hour of searching all corners of internet, I ended up here. I still don't know how to make this.
Yes, I know how to save current instance using onSaveInstanceState and onRestoreInstanceState
but no one in the internet explained it with a large complex coding like dynamically created views, many textviews and calculations,etc. Everyone explaining this with only one or two textViews and I was like "How someone can create an app with only few TextViews!?!" like below:
onSaveInstanceState()
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState");
final EditText textBox =
(EditText) findViewById(R.id.editText);
CharSequence userText = textBox.getText();
outState.putCharSequence("savedText", userText);
}
onRestoreInstanceState()
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "onRestoreInstanceState");
final EditText textBox =
(EditText) findViewById(R.id.editText);
CharSequence userText =
savedInstanceState.getCharSequence("savedText");
textBox.setText(userText);
}
I can totally understand this above method. But What to do if we complete a quite complicated coding and want to save & restore the state I have completed all my complex coding stuff and landed in this problem.
I'm sure there will be a simple way to achieve this. Please understand my problem. Help me.
If I understand correctly, you want to save the current state of the page even the page changes, if this is the case, it can be solved by data binding as follows:
1.enable data binding in Gradle
2. in XML file put your layout into layout tag
<layout>
...// your activity view layout
</layout>
then define it in your activity :
private lateinit var binding: FragmentNameBinding
4.add this expression in onCreate or onCreateView(for fragment)
if (!(::binding.isInitialized)) {
//initialize you layout file and what ever you want
}
//then initialize what you want to not change after the layout
changed and back to it
Related
Here's a simple app, I'm trying to create logs in the printToLogs method.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("Log0","test");
}
public void printToLogs(View view){
TextView menuTextView1 = findViewById(R.id.menu_item_1);
TextView menuTextView2 = findViewById(R.id.menu_item_2);
TextView menuTextView3 = findViewById(R.id.menu_item_3);
String item1 = (String) menuTextView1.getText();
String item2 = (String) menuTextView2.getText();
String item3 = (String) menuTextView3.getText();
Log.v("Log1",item1);
Log.v("Log2",item2);
Log.v("Log3",item3);
}
but logs with the tags Log1, Log2, Log3 are not shown at all in the logcat, what does show up is the Log0 in the onCreate method, but the other ones in printToLogs never show up when I search for them at all. I attempted re-installing the app and restarting logging. That didn't work.
The menu items are: Mango sorbet, Blueberry pie, Chocolate lava cake. And yes, I tried searching for them, and they are not in the logcat either.
If this is your actual code, you aren't even calling printToLogs in the onCreate method. You should be more diligent before posting something simple like this.
Barring a serious runtime environment issue, this problem should be fairly easy to solve.
It seems as if the printToLogs(View view) method is to be executed in response to the user clicking a button. If so, try including the following line in your activity_main.xml if you haven't already:
android:onClick="printToLogs"
This will bind the button on the UI with the printToLogs(View view) method.
If, on the other hand, printToLogs(View view) is intended to be a standalone method (i.e. one that should execute regardless of user input) it should not accept a View as an argument. For your purposes, its parameter list should be completely empty. In other words, the method signature should read:
public void printToLogs()
Also, it should be called within the onCreate(Bundle savedInstances) method. Add the following to the onCreate(Bundle savedInstances) method:
printToLogs();
This will initiate the execution of the method as soon as the app begins to run.
Make sure the logcat filter is set to "Verbose" when testing like so: (img is link since apparently I need 10 rep. to embed images into answers directly)
logcat filter
heyy add your method/function name in your button by using property section or just android:onClick in your xml file and then it will be solved
This question already has answers here:
Handle screen rotation without losing data - Android
(8 answers)
Closed 6 years ago.
I have activity_main.xml layout file and I created landscape layout file in "layout-land" directory. Obviously both files have the same names.
Landscape and main layouts work good, but when I move my phone to swich layout, all my textViews and editTextes changes to default values.
You have to save your information in a bundle and restore it during OnCreate().
https://developer.android.com/training/basics/activity-lifecycle/recreating.html
Every time you rotate your phone, configuration change happen and a new instance of your activity is created. That's why your Textview and Edittext are set to default values. However, if your views have id's set on them in the xml, then the values set on them will not be lost during a configuration change. If you don't want to set id then another way would be to save your Textview and Edittext values in onSaveInstanceState and restoring them in onRestoreInstanceState. For example to save your textview and edittext values follow the following code:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("arg1", textview1.getText());
outState.putString("arg2", edittext1.getText().toString());
......
}
To restore the saved values follow following code:
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
textview1.setText(savedInstanceState.getString("arg1"));
edittext1.setText(savedInstanceState.getString("arg2"));
......
}
You can read more about this here: https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
Is it possible to set image resource in onCreate method before loading layout.
For example:
On main layout I have images instead of buttons, so there is no button "Play", instead there is an image on which "Play" is drawn.
But, on other hand, user can change languages, so if user choses German there has to be different image on main layout.
I know how to change picture on some event, but is it possible to do it in onCreate method.
Logic would probably be something like:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences options= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String language= options.getString("language", "en");
setLocal(language);
setContentView(R.layout.activity_main);
ImageView play= (ImageView)findViewById(R.id.play);
if(language=="en")
play.setImageResource(R.drawable.play_en);
else if(language=="de")
play.setImageResource(R.drawable.play_de);
}
Of course, this doesn't change the picture because image is already loaded, but I hope you get what I want to achieve.
What you wan't to do can be done using localization on your resources, I think this is te correct and easily way to do it.
You can check how, here: http://developer.android.com/guide/topics/resources/localization.html
I read that Android automatically saves the content of EditText objects when an application is about to be stopped or killed. However, in my app the content of an EditText is lost when screen orientation changes.
Is it normal behaviour? Do I then have to manually save/restore its content with onSaveInstanceState/onRestoreInstanceState? Or is there an easier method to tell Android to save it end restore it?
Edit:
I create the EditText object programmatically, not in XML. This turns out to be related to the problem (see accepted answer below).
This is not normal behavior.
First and foremost, ensure that you have IDs assigned to your EditText controls in the layout XML.
Edit 1: It just needs an ID, period. If you're doing this programmatically, it will lose state unless it has an ID.
So using this as a quick & dirty example:
// Find my layout
LinearLayout mLinearLayout = (LinearLayout) findViewById(R.id.ll1);
// Add a new EditText with default text of "test"
EditText testText = new EditText(this.getApplicationContext());
testText.setText("test");
// This line is the key; without it, any additional text changes will
// be lost on rotation. Try it with and without the setId, text will revert
// to just "test" when you rotate.
testText.setId(100);
// Add your new EditText to the view.
mLinearLayout.addView(testText);
That will solve your problem.
Should that fail, you'll need to save and restore state yourself.
Override onSaveInstanceState like so:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("textKey", mEditText.getText().toString());
}
And then restore in OnCreate:
public void onCreate(Bundle savedInstanceState) {
if(savedInstanceState != null)
{
mEditText.setText(savedInstanceState.getString("textKey"));
}
}
Also, please don't use android:configChanges="orientation" to try to accomplish this, it's the wrong way to go.
could you use android:freezesText="true" in the xml layout?
The easiest way I found to save an object on onSaveInstanceState is to implement serializable and put in bundle
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("myObj", myObj);
}
where myObj class implements serializable and in onCreate() method
if (savedInstanceState != null && savedInstanceState.getSerializable("myObj") != null) {
myObj = ((MyObj) savedInstanceState.getSerializable("myObj"));
}
One possible cause is that you override onSaveInstanceState but you forget to call the same for super class
super.onSaveInstanceState(outState);
State of all views in activity is auto saved UNLESS you override this functionality. Even if this is obvious, mistakes are possible.
You just need UNIQUE ID for the edit text. Make sure if you dynamically add edit text, chances of having same id can cause not restoring the text.
Same way if you add in xml, use unique id. Hope it will help someone.
FYI: EditText by default having setFreezesText as true
Well basicly I have a textview and when the application is created it sets a string as the textviews text not hard, but I get a force close error when I run the app on my phone.
TextView sdcard=(TextView)findViewById(R.id.sd_textview);
sdcard.setText(R.string.not_mounted);
Then I have a error on a togglebutton also
ToggleButton silent=(ToggleButton)findViewById(R.id.silentbutton);
silent.setChecked(false);
And I have errors for all my other buttons/textviews can anyone help, please?!
EDIT:
I cant post pics because I am a new member, :(
Link to imgshack http://imageshack.us/photo/my-images/849/unledggp.png/
If code for the whole textview snippet.
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_UNMOUNTED)) {
TextView sdcard=(TextView)findViewById(R.id.sd_textview);
sdcard.setText(R.string.not_mounted);
}
OnCreate Function
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
checkSD();
checkRing();
checkWifi();
checkBt();
}
Look for all instances of sd_textview and make sure the one that you're trying to reference is a TextView. If you want more clarity you can debug your code and see what object is actually being returned by not casting into a TextView:
View sdcard = findViewById(R.id.sd_textview); //debug this
//you can also log the View object to see the type
Log.d("Test", "" + sdcard);
Looking at your error log (assuming its the right error log) you have a ClassCastException in the checkWifi method. Edit your question and include ALL of the onCreate method and all of the checkWifi method, but I expect you are using the same id for multiple views.
Two things I can think of (although seeing more code would help).
Make sure you have called setContentView(R.layout.main) (or whatever your layout file is called). Do this BEFORE any attempt to use findViewById(...).
Secondly sdcard.setText(R.string.not_mounted); in this statement R.string.not_mounted is a resource ID (int) and not a string. You would need to use...
sdcard.setText(getString(R.string.not_mounted));