2

See the following Activity:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinearLayout linearLayout = (LinearLayout) findViewById(R.id.root);

        for (int i = 0; i < 8; i++) {

            EditText editText = (EditText) LayoutInflater.from(this).inflate(R.layout.edittextlayout, null);
            editText.setText("#" + i);
            linearLayout.addView(editText);

        }

    }

}

The layout R.layout.activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


    </LinearLayout>

</LinearLayout>

and the layout R.layout.edittext_layout:

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

After starting the app it looks like I would expect: every EditText being filled with it's index.

enter image description here

After rotating the device though, the Activity looks like this:

enter image description here

All the EditTexts are there, but they all contain the same text.

What baffles me even more is that this doesn't happen when creating the EditTexts programmatically with

EditText editText = new EditText(this)

instead of inflating it from a layout.

What's happening there?

You can check out my example and try for yourself here.

EDIT: This is not a duplicate of this question as in my case the text in the EditText does not double but get mixed up between different EditTexts.

Community
  • 1
  • 1
fweigl
  • 21,278
  • 20
  • 114
  • 205

2 Answers2

4

Try to set some ID for each View.

For example:

view.setId(id);  

Or use

onSaveInstanceState() - onRestoreInstanceState()

for saving info.

Tamil Selvan C
  • 19,913
  • 12
  • 49
  • 70
Tronum
  • 707
  • 3
  • 13
  • Clever idea. It can solve the problem I mentioned and prevent android from assigning wrong values to views. – Arda Kara Jul 09 '15 at 12:30
  • Thanks, that actually prevents the effect from happening. Do you have an idea why? – fweigl Jul 09 '15 at 12:47
  • @Ascorbin as I mentioned in my answer without the id's android assigns the last value it read to all views. To prevent that you can handle data yourself or set a different id to each view. – Arda Kara Jul 09 '15 at 12:52
  • @Ascorbin It's related to inner mechanisms in android. It's a bug, I think. On reCreate, manager can correctly identify only views with Ids. I think they have one field for one kind of view(or something like that) and last view rewrite it field on saving. So all same views receive that value on restore... IMHO. – Tronum Jul 09 '15 at 13:38
  • @Tronum The views shouldn't even be retained though. After orientation change they should always be created 'from scratch', right? – fweigl Jul 09 '15 at 21:49
  • @Ascorbin not in all times. It's true if your activity or fragment was recreated. But you can turn off that behaviour. Anyway I think that your problem was resolved? – Tronum Jul 10 '15 at 08:24
0

The problem is your activity recreates on every orientation and saved instance data handled wrong by Android. You can avoid it by setting an id to your dynamically created views or you can Override onSaveInstanceState method to save your data like text in your edittexts and recover it on onCreate method like so:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Check if we're recreating
    if (savedInstanceState != null) {
        // Restore value of edittext from saved state
            editText.setText(savedInstanceState.getString("edittext"));
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString("edittext", editText.getText().toString());
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

If you encounter any problem similar after doing this try to Override onRestoreInstanceState method to prevent android from doing your work.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    //do nothing
}
Arda Kara
  • 501
  • 6
  • 24