How to retain EditText data on orientation change?

2019-01-17 10:03发布

I have a Login screen which consists of 2 EditTexts for Username and Password. My requirement is that on orientation change , input data(if any) in EditText should remain as it is and a new layout should also be drawn. I have 2 layout xml files- one in layout folder and other in layout-land folder. I am trying to implement following 2 approaches but none of them is perfect:

(1) configChanges:keyboardHidden - In this approach, I don't provide "orientation" in configChanges in manifest file. So I call setContentView() method in both onCreate() and onConfigurationChanged() methods. It fulfills both my requirements. Layout is changed and input data in EditTexts also remains as it is. But it has a big problem :

When user clicks on Login button, a ProgressDialog shows until server-response is received. Now if user rotates the device while ProgressDialog is running, app crashes. It shows an Exception saying "View cannot be attached to Window." I have tried to handle it using onSaveInstanceState (which DOES get called on orientation change) but app still crashes.

(2) configChanges:orientation|keyboardHidden - In this approach, I provide "orientation" in manifest. So now I have 2 scenarios:

(a) If I call setContentView() method in both onCreate() and onConfigurationChanged(), Layout is changed accordingly but EditText data is lost.

(b) If I call setContentView() method in onCreate() , but not in onConfigurationChanged(), then EditText data is not lost but layout also not changes accordingly.

And in this approach, onSaveInstanceState() is not even called.

So I am in a really intimidating situation. Is there any solution to this problem? Please help. Thanx in advance.

11条回答
老娘就宠你
2楼-- · 2019-01-17 10:45

in onConfigurationChanged method, first get the data of both the edit texts in global variables and then call setContentView method. Now set the saved data again into the edit texts.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-01-17 10:46

Adding to the EditText the atribute

android:id="@id/anything"

worked to me.

查看更多
4楼-- · 2019-01-17 10:46

As pointed out by Yalla T it is important to not recreate the fragment. The EditText will not lose its content if the existing fragment is reused.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.activity_frame);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    // Display the fragment as the main content.
    // Do not do this. It will recreate the fragment on orientation change!
    // getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new Fragment_Places()).commit();

    // Instead do this
    String fragTag = "fragUniqueName";
    FragmentManager fm = getSupportFragmentManager();
    Fragment fragment = (Fragment) fm.findFragmentByTag(fragTag);
    if (fragment == null)
        fragment = new Fragment_XXX(); // Here your fragment
    FragmentTransaction ft = fm.beginTransaction();
    // ft.setCustomAnimations(R.xml.anim_slide_in_from_right, R.xml.anim_slide_out_left,
    // R.xml.anim_slide_in_from_left, R.xml.anim_slide_out_right);
    ft.replace(android.R.id.content, fragment, fragTag);
    // ft.addToBackStack(null); // Depends on what you want to do with your back button
    ft.commit();

}
查看更多
叛逆
5楼-- · 2019-01-17 10:48

The following should work and is standard to the activities and fragments

@Override
public void onSaveInstanceState (Bundle outState) 
{
     outState.putString("editTextData1", editText1.getText().toString());
     outState.putString("editTextData2", editText2.getText().toString());

     super.onSaveInstanceState(outState);
}

@Override
public void onCreate(Bundle savedInstanceState)
{
      super.onCreate();

      ... find references to editText1, editText2

      if (savedInstanceState != null)
      {
           editText1.setText(savedInstanceState.getString("editTextData1");
           editText2.setText(savedInstanceState.getString("editTextData2");
      }
}
查看更多
Summer. ? 凉城
6楼-- · 2019-01-17 10:50

Im restoring instance to restore values and it works fine for me :)

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.addtask2);
    if(savedInstanceState!=null)
     onRestoreInstanceState(savedInstanceState);

}
查看更多
ら.Afraid
7楼-- · 2019-01-17 10:51

By default, Edittext save their own instance when changing orientation.

Be sure that the 2 Edittexts have unique IDs and have the same IDs in both Layouts.

That way, their state should be saved and you can let Android handle the orientation change.

If you are using a fragment, be sure it has a unique ID also and you dont recreate it when recreating the Activity.

查看更多
登录 后发表回答