Handle Screen Rotation Without Losing Data - Android

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 use
seekbar_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 calls onSaveInstanceState() before it destroys your
    activity so that you can save data about the application state. You
    can then restore the state during onCreate() or
    onRestoreInstanceState().

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:

  1. 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.

  2. 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



Leave a reply



Submit