Handle screen rotation without losing data - Android
can use override method onSaveInstanceState()
and onRestoreInstanceState()
.
or to stop calling onCreate()
on screen rotation just add this line in your manifest xml android:configChanges="keyboardHidden|orientation"
note: your custom class must implements Parcelable
example below.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("obj", myClass);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
myClass=savedInstanceState.getParcelable("obj"));
}
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
/** save object in parcel */
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
/** recreate object from parcel */
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Handle screen rotation progress without losing data by using Seekbar - Android Kotlin
You are passing string to the progress function of seekbar.
We need to pass integer.
So, simply useseekbar_weight.progress = value.toInt()
UPDATE AFTER GOING THROUGH YOUR CODE:
In your code, in the setVariable()
function, you are setting some UI's according to the Units user picked.
While doing that, you are setting your progress of the seekbar to 0. And this function is being called after the progress value is restored from onRestoreInstateState
. After it gets restored, you are again setting it back to zero from setVariable()
function.
So, you just need to remove 8 lines (which are used to set seekbar progress and text to show seekbar progress) from your setVariable()
function.
So, your setVariable()
function should look like:
private fun setVariable() {
//Set the text of units and the max progress
spinner_units.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
if (position == 0) {
text_weight.text = "Weight (kg)"
text_height.text = "Height (cm)"
seekbar_weight.max = 450
seekbar_height.max = 250
number_picker_age.value = 2
bmi_meter.speedTo(0F)
} else if (position == 1) {
text_weight.text = "Weight (ibs)"
text_height.text = "Height (in)"
seekbar_weight.max = 770
seekbar_height.max = 80
number_picker_age.value = 2
bmi_meter.speedTo(0F)
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
}
UPDATE 2: AFTER UPDATED REQUIREMENT
For your updated requirement here you can go:
Bring back those 8 lines those were deleted from setVariable()
method.
In your strings.xml
file, add one item 'Select' in the string array for the spinner.
<string-array name="units">
<item>Select</item>
<item>Metric</item>
<item>Imperial</item>
</string-array>
In MainActivity
, override onPause()
method and set the spinner to position 0.
override fun onPause() {
super.onPause()
spinner_units.setSelection(0)
}
That should solve your problem. If not please comment back.
Losing data when rotate screen
By default, when the screen is rotated your Activity is killed and restarted. To make sure no data is lost, you need to properly save and restore your data using the lifecycle methods. See Saving Persistent State.
Android: Efficient Screen Rotation Handling
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (onDestroy()
is called, followed by onCreate()
).
- To properly handle a restart, it is important that your activity
restores its previous state through the normal Activity lifecycle, in
which Android callsonSaveInstanceState()
before it destroys your
activity so that you can save data about the application state. You
can then restore the state duringonCreate()
oronRestoreInstanceState()
.
However, you might encounter a situation in which restarting your application and restoring significant amounts of data can be costly and create a poor user experience. In such a situation, you have two other options:
Retain an object during a configuration change
Allow your activity to restart when a configuration changes, but carry a stateful Object to the new instance of your activity.
Handle the configuration change yourself
Prevent the system from restarting your activity during certain configuration changes, but receive a callback when the configurations do change, so that you can manually update your activity as necessary.
So, As per your data operation and coast of user experience with application you can choose what is best for you..
EDIT: As per your need for just change the layout I think you have to use onConfigurationChanged()
and do the changes in it.
Data from textView deleting after i rotate screen after i implemented onSaveInstance and onRestoreInstance
Yes, you need to use onSaveInstanceState
. This methods will save your variables which you have in your textViews or something else. In your case you need to declare your views like findViewById
in onSaveInstanceState
and onRestoreInstanceState
. You can try something like this, this code is working:
public class MainActivity extends AppCompatActivity {
Button Btn;
TextView textView;
String cnt = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Btn = (Button) findViewById(R.id.button);
}
public void onBtnClick(View view) {
textView = (TextView) findViewById(R.id.textView);
textView.setText("Hehe");
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
textView = (TextView) findViewById(R.id.textView);
cnt = (String) textView.getText();
outState.putString("count", cnt);
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
cnt = savedInstanceState.getString("count");
textView = (TextView) findViewById(R.id.textView);
textView.setText(cnt);
}
}
How to handle screen orientation change when progress dialog and background thread active?
When you switch orientations, Android will create a new View. You're probably getting crashes because your background thread is trying to change the state on the old one. (It may also be having trouble because your background thread isn't on the UI thread)
I'd suggest making that mHandler volatile and updating it when the orientation changes.
Related Topics
How to Use Web Camera in Android Emulator to Capture a Live Image
Android 2.1 Programmatically Unmount Sdcard
Android: Activity Getting Destroyed After Calling Camera Intent
Different Font Size of Strings in the Same Textview
Embedding Ads Within Recyclerview
Misbehavior When Trying to Store a String Set Using Sharedpreferences
Android Studio - Emulator - Eglsurfaceattrib Not Implemented
Ffmpeg for a Android (Using Tutorial: "Ffmpeg and Android.Mk")
Accessing Sharedpreferences Through Static Methods
Android Studio Gradle Configuration with Name 'Default' Not Found
Why My App Is Not Showing Up on Tablets in Google Play
How to Record Phone Calls in Android
Locationsettingsrequest Dialog to Enable Gps - Onactivityresult() Skipped
Listview Getchildat Returning Null for Visible Children
Android.Content.Activitynotfoundexception: Unable to Find Explicit Activity Class