Android switching to layout-land [duplicate] - android

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

Related

Saving whole instance of an activity

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

Must be one of: View.VISIBLE, View.INVISIBLE, View.GONE [duplicate]

This question already has answers here:
Not able to dynamically set the setVisibility() parameter
(3 answers)
Closed 7 years ago.
I am saving and restoring a views visibility in one of my activities. I do this by calling mButton.getVisibility() and saving this in a Bundle. In onRestore where I get the int value it is showing an error.
Must be one of: View.VISIBLE, View.INVISIBLE, View.GONE less... (Ctrl+F1)
Reports two types of problems:
- Supplying the wrong type of resource identifier. For example, when calling Resources.getString(int id), you should be passing R.string.something, not R.drawable.something.
- Passing the wrong constant to a method which expects one of a specific set of constants. For example, when calling View#setLayoutDirection, the parameter must be android.view.View.LAYOUT_DIRECTION_LTR or android.view.View.LAYOUT_DIRECTION_RTL.
The code compiles and runs with no errors
code
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
savedInstanceState.putInt("BUTTON_VISIBILITY", mButton.getVisibility());
super.onSaveInstanceState(savedInstanceState);
}
public void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mButton.setVisibility(savedInstanceState.getInt("BUTTON_VISIBILITY"));
// savedInstanceState.getInt("BUTTON_VISIBILITY") is underlined red
}
As I have just commented, you can add #SuppressWarnings("ResourceType"). Hope this helps!
Alt-Enter

Set image resource in onCreate method

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

EditText not automatically saved on screen orientation change

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

Android memory usage

i am building an android application but i have some questions about
the memory usage.
Most of the data i need and use are string arrays stored in the xml strings file. I used arrays because firstly the biggest array will have up to 30 items and secondly there won't be any updating or deleting or inserting items through the app.
All the custom adapters i created are following googles' guidlines (the fast way - using the holder class)
As the user switches between the activities, depending on the selections he makes different arrays are loaded in the listviews.
Does android clears the memory each array allocates if its not in use? should i do that?
I ve used MAT also to check how the app uses memory and to check for leaks etc..and i thing that everything is fine. I also use a few png icons/images.
The app gets 5MB when it starts, goes up and down up to 8.5-9MB as the user plays around.
Thanks in advance for any help!
It's possible the Android OS will kill your Activities (without focus) on the stack if memory is needed. When your Activity is killed in this way, onSaveInstanceState(Bundle outState) is called. You should save your string array here.
When onCreate(Bundle savedInstanceState) is called in your Activity, if savedInstanceState is not NULL, then it means your Activity was previously killed by the OS and you need to repopulate your string array from that bundle.
ex:
String [] stringArray;
...
protected void onCreate(Bundle savedInstanceState)
{
if (savedInstanceState != null)
{
stringArray = savedInstanceState.getStringArray("some_key");
}
}
protected void onSaveInstanceState (Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putStringArray("some_key", stringArray);
}
This is described in more detail here: http://developer.android.com/reference/android/app/Activity.html

Categories

Resources