0

I am dynamically adding views to Android and am seeing a really weird result which makes little to no sense. Here is the code that shows the bug:

private static int count = 0;

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

    count++;

    // Allow 'up' action for actionBar
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setTitle("TEST");
    setContentView(R.layout.test);

    LinearLayout testLinear = (LinearLayout)findViewById(R.id.testLinear);

    LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View view = inflater.inflate(R.layout.job_step_text, null, false);
    TextView title = (TextView) view.findViewById(R.id.jobStepTextTextView);
    final EditText editText = (EditText)view.findViewById(R.id.jobStepEditText);
    title.setText("Field 1");
    editText.setText("Value 1");

    testLinear.addView(view);

    if(count == 1) {
        View view2 = inflater.inflate(R.layout.job_step_text, null, false);
        TextView title2 = (TextView) view2.findViewById(R.id.jobStepTextTextView);
        final EditText editText2 = (EditText)view2.findViewById(R.id.jobStepEditText);
        title2.setText("Field 2");
        editText2.setText("Value 2");

        testLinear.addView(view2);
    }

}

First time round the Activity is as follows:

Field 1: [ Value 1 ]

Field 2: [ Value 2 ]

Then when the device rotates the following is shown:

Field 1: [ Value 2 ]

Can anyone help? It seems that after the first time round the line:

final EditText editText = (EditText)view.findViewById(R.id.jobStepEditText);

is fetching an old reference and not calling setText()? When the screen rotates the line of code which sets the text field to 'Value 2' isn't even called and yet that's the result in the Field 1 text box.

Can anyone help?

By the way - a way to fix this is to give each EditText a unique ID before adding it to the view... but that makes no sense... Surely the inflated View has no knowledge of any other views (past or present) until testLinear.addView(view); is added?

Thanks in advance.

user3707
  • 1,470
  • 2
  • 15
  • 21

1 Answers1

0

The onSaveInstanceState in the Activity (your super class) captures information about the attached content view and reloads it for you during onCreate() So when the Activity gets recreated after the device rotates, values are put into views found by ID as soon as you call setContentView(). This can produce surprising results if you are changing your layout on-the-fly.

One approach I have used is to call findViewById to see if the child view is already present, before adding it "by hand".

Another approach would be to inflate the layout first, make your adjustments to it, then call setContentView.

[I don't quite understand Android's reason for doing this -- maybe to allow super-simple applications to skip the onSaveInstanceState/reload from bundle process??)

Dale Wilson
  • 9,166
  • 3
  • 34
  • 52
  • Perfect, thanks Dale. FYI for anyone else - I think this is the same issue: http://stackoverflow.com/questions/13914970/why-edittext-in-a-custom-compound-view-is-re-using-the-text-entered-in-another-c – user3707 Nov 06 '13 at 21:03