Android EditText content multiplies when orientation changed - android

I have weird situation with EditText.
Situation:
set device to landscape mode
enter text to EditText and press
"DONE"
change orientation
EditText contains doubled text that
was typed
the code:
private EditText enterText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
enterText = (EditText) findViewById(R.id.enterText);
}
If I comment the line with findViewById, everything is working properly.
Any ideas why this happens?
EDIT: I've double checked and it happens every time, not only if the line I was written about is commented.. :-\
EDIT2: It happens only on first orientation change event. Every next is OK..

Every time you rotate your phone the Activity restarts, which probably calls something that causes your text to be written again somehow. This is part of the OS and a bit annoying, here is that to do.
If you in your manifest add:
android:configChanges="orientation"
to the activity node in which the rotation is done, you'll have to override the onConfigurationChanged.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.myLayout);
}
Whenever your phone rotates the overriden method will call and you can do a special initialization like ignore the input if there was an input earlier and such. Hope this gets you on the right track!
PS: You can also pipeline the configChanges with different other "values/configs". Such as keyboardHidden and many others.
They are listed on the following link

Related

Device Orientation Destroy Activity

I've got my app working for the most part, but I've got buttons and text views with text that change based on some state variables. When I change the device's orientation it destroys and recreates the activity in the new orientation. I've tried adding
android:configChanges="orientation"
to the manifest file. I've also tried overriding the onConfigurationChanges method to "do nothing" but the text still reverts to default.
I know I can lock the user in to one orientation, but I would rather have the app usable in either orientation.
Alternatively, is there a way to determine which orientation the user opened the app in and lock them in that orientation until they restart the app?
Edit:
Thank you Kabir,
android:configChanges="orientation|screenSize"
works perfectly
For API 12 and below:
android:configChanges="orientation"
if you are targeting API 13 or above
android:configChanges="orientation|screenSize"
Actually orientation changing works by destroying and recreating an activity. Some views are able to save theirs states, others no. TextView doesn't save its state (in this case text) as it tends to show static text. If you want to save TextView's state during the configuration changes, you can do as following:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
/*
1st argument is key, 2nd is value to save
*/
outState.putString("savedText", myTextView.getText().toString());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
/*
The argument is key to get saved string
*/
myTextView.setText(savedInstanceState.getString("savedText"));
}
These onSaveInstanceState() and onRestoreInstanceState() are Activiy's methods.

How to set the Background Color of a View in onRestoreInstanceState()

I'm currently trying to learn to work with Views and states. I'm normally able to set its color in functions like in the following:
View mColorRegion = findViewById(R.id.color_region);
mColorRegion.setBackgroundColor(Color.CYAN);
However, I can't seem to be able to set the color in an onRestoreInstanceState(), as
mColorRegion.setBackgroundColor(savedInstanceState.getInt("color"));
However, working with the same View as a TextView, I'm able to restore text as in the following:
TextView mText = (TextView)findViewById(R.id.color_region);
mText.setText(savedInstanceState.getString("text");
What's the difference, and how I can set the background color in onRestoreInstanceState()?
EDIT: Since the original post, I've noticed two things:
1) mColorRegion.setBackgroundColor(Color.CYAN) doesn't seem to work in onCreate() either.
2) Even though the following function correctly changes the View color when a button is pressed, it doesn't work if I call it directly from onRestoreInstanceState():
public void centerButton1(View clickedButton) {
mColorRegion.setBackgroundColor(Color.CYAN);
}
Hmm...
So I found a "half-solution". If you add the following line to AndroidManifest.xml, it will preserve the color during orientation changes:
android:configChanges="orientation|screenSize"
However, this still doesn't answer why I can set the text but not the color in onRetoreInstanceState() or onCreate()...
Many people frown upon using android:configChanges="orientation|screenSize", like Google's Dianne Hackborn. For one, It will make the process of switching between multiple layouts for your app very difficult (for example, if you want one layout for landscape, and one for portrait) since you'll have to do all of the work that Android normally does automatically for you, in onConfigurationChanged().
Anyway, I also had this sort of problem. I was creating a DialogPreference, and upon rotation I couldn't change the progress of a SeekBar in onRestoreInstanceState(savedInstanceBundle)...so this is what I suggest if you cannot use onCreate(savedInstanceBundle) or onActivityCreated(savedInstanceBundle) (for fragments) to restore the state of your view objects:
1) Make a private class member called "mRestoredBGColor",
private int mRestoredBGColor = -1;
2) In onRestoreInstanceState():
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
mRestoredBGColor = savedInstanceState.getInt("key_you_used_in_onSaveInstanceState");
}
3) Then in onResume(), because onRestoreInstanceState() is called after onStart(), but before onResume()
#Override
public void onResume(){
super.onResume();
if(mColorRegion != null && mRestoredBGColor != -1){
mColorRegion.setBackgroundColor(mRestoredBGColor);
mRestoredBGColor = -1; //to make sure it only sets this once per rotation.
}
}
Hope this helps somebody. I believe there is always another way (except when you want quickly rotating WebViews...) than using android:configChanges="orientation|screenSize".

How to retain component properties in screen rotate event?

I m very new to android development, i just make some simple application to practice which have "TextView" and "Button" in it. On each click the "TextSize" of TextView increase by 10. But after increasing TextSize when I rotate the screen the TextSize of TextView goes back default value.
Anybody please tell me how to handle this, so the TextView retain its size evenafter screen rotates.
-ZKhan
When you change the orientation then your onCreate() get called implicitly so to remove that
in your Manifest.xml just add this in application tag android:configChanges="orientation",
this tells the system that you are going to handle orientation by your own.
Then manage your logic in #Override onConfigurationChanged().
When configuration changed your activity is destroyed and it starts again from onCreate method.So you are seeing initial size.You can use below method to save the changed size and give it back while activity is again in onCreate.You can use shared preference to store changes
#Override
public void onConfigurationChanged(Configuration newConfig) {
}

TextView's text disappearing when device rotated

I am writing a phone dialer app for android. I created a layout for keypad, which contains a TextView and 10 buttons. Buttons are as keys for 10 digits(0 to 9) and TextView is for displaying the number according to keys pressed.
In my app, i am appending the text ("0" or "1", etc.) to the TextView for each button pressed. If i pressed the buttons 1, 2, 3 then the text on TextView is 123.
The problem is, let's take the screen is in landscape mode and TextView contains 123, if i turn it, in portrait mode no text on TextView.
Please Help Me Regarding this.
What #jeet recommended didn't work for me. I had to add "screenSize". This is the line you should add in your manifest.xml in the <activity> node of your activity:
android:configChanges="keyboardHidden|orientation|screenSize"
Thus, the complete node may look like this:
<activity
android:name=".YourActivity"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="#style/AppTheme.NoActionBar">
Please check on orientation change, on create method is called, which requires all the views to be created again, so you need to use one of the following methods:
use onSavedInstance method and save the states of components/views to bundle.
Just use following flag true in your manifest file in activity tag android:configChanges="keyboardHidden|orientation". like below:
<activity android:name=".SampleActivity" android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation">
...
</activity>
The reason for this is due to Android basically destroying the activity and creating it again every time you rotate the device. This is mainly to allow for different layouts based on portrait/landscape mode.
The best way to handle this is to store whatever data you need to keep within the Activity Bundle, by responding to the onSavedInstance event (called just before Android destroys the activity), and then reapplying those in the standard onCreate event.
Although you can add "orientation" to the configChanges property, keep in mind that you're basically telling Android that you're going to be handling everything relating to orientation change yourself - including changing layout, etc.
To preserve a TextView's text, you can simply set the TextView's freezesText property to true.
As in:
<TextView
...
android:freezesText="true"
.../>
This is the accepted answer here:
Restoring state of TextView after screen rotation?
If someone is still having troubles... this did the trick for me
public class BranjeKP extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_branje_kp);
//...
}
#Override
protected void onSaveInstanceState(Bundle out) {
super.onSaveInstanceState(out);
out.putString("TVNazivPod", TVNazivPodatka.getText().toString());
out.putString("TVEnotaMere", TVEnotaMere.getText().toString());
}
#Override
protected void onRestoreInstanceState(Bundle in) {
super.onRestoreInstanceState(in);
TVNazivPodatka.setText(in.getString("TVNazivPod"));
TVEnotaMere.setText(in.getString("TVEnotaMere"));
}
You basically save any values you want before rotation (that's when onSaveInstanceState is called) into a Bundle and after rotation (onRestoreInstanceState) you just pull all values out from Bundle.
Just to clarify, TVNazivPodatka and TVEnotaMere are TextView widgets.
...with a help from
How to prevent custom views from losing state across screen orientation changes

Android : Save application state on screen orientation change

I have seen the following links before posting this question
http://www.devx.com/wireless/Article/40792/1954
Saving Android Activity state using Save Instance State
http://www.gitshah.com/2011/03/how-to-handle-screen-orientation_28.html
How to save state during orientation change in Android if the state is made of my classes?
I am not getting how should i override the following function :
#Override
public Object onRetainNonConfigurationInstance() {
return someExpensiveObject;
}
In my application i have layout with one editext visible and other editext get visible when the data of first editext validates to true.I have set the visbility of all other editextes and textviews to false and make them visible after validating.
So in my activity if the screen orientation is changed then all the items having android:visibility="false" get invisible.
I have also came to know that when our activities screen orientation changes it calls onStop() followed by onDestroy() and then again starts a fresh activity by calling onCreate()
This is the cause .. But i am not getting how to resolve it ..
Here You can see the screenshots of my application :
in this image all fields are loaded
and in another image when the screen orientation is changed to landscape they are all gone
Any link to tutorial or piece of code will be highly appreciable.
And also my application crashes when a progress dialog is shown up and i try to change screen orientation.How to handle this ??
Thanks
Well if you have the same layout for both screens then there is no need to do so just add below line in your manifest in Activity node
android:configChanges="keyboardHidden|orientation"
for Android 3.2 (API level 13) and newer:
android:configChanges="keyboardHidden|orientation|screenSize"
because the "screen size" also changes when the device switches between portrait and landscape orientation.
From documentation here: http://developer.android.com/guide/topics/manifest/activity-element.html
There is another possibility using which you can keep the state as it is even on Orientation change using the onConfigurationChanged(Configuration newConfig).
Called by the system when the device configuration changes while your activity is running. Note that this will only be called if you have selected configurations you would like to handle with the configChanges attribute in your manifest. If any configuration change occurs that is not selected to be reported by that attribute, then instead of reporting it the system will stop and restart the activity (to have it launched with the new configuration).
At the time that this function has been called, your Resources object will have been updated to return resource values matching the new configuration.
There are 2 ways of doing this, the first one is in the AndroidManifest.xml file. You can add this to your activity's tag. This documentation will give you an in depth explanation, but put simply it uses these values and tells the activity not to restart when one of these values changes.
android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"
And the second one is: overriding onSaveInstanceState and onRestoreInstanceState. This method requires some more effort, but arguably is better. onSaveInstanceState saves the values set (manually by the developer) from the activity before it's killed, and onRestoreInstanceState restores that information after onStart() Refer to the official documentation for a more in depth look. You don't have to implement onRestoreInstanceState, but that would involve sticking that code in onCreate().
In my sample code below, I am saving 2 int values, the current position of the spinner as well as a radio button.
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
spinPosition = options.getSelectedItemPosition();
savedInstanceState.putInt(Constants.KEY, spinPosition);
savedInstanceState.putInt(Constants.KEY_RADIO, radioPosition);
super.onSaveInstanceState(savedInstanceState);
}
// And we restore those values with `getInt`, then we can pass those stored values into the spinner and radio button group, for example, to select the same values that we saved earlier.
#Override
public void onRestoreInstanceState(#NotNull Bundle savedInstanceState) {
spinPosition = savedInstanceState.getInt(Constants.KEY);
radioPosition = savedInstanceState.getInt(Constants.KEY_RADIO);
options.setSelection(spinPosition, true);
type.check(radioPosition);
super.onRestoreInstanceState(savedInstanceState);
}

Categories

Resources