0

On this documentation page about onSaveInstanceState I read:

The default implementation takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, ...

and interpret as:

  • if I generate a LinearLayout L containing an ImageView I and a Fragment F

  • and I assign an ID to L, I, and L

  • then L, I, and F are saved when onSaveInstanceState(.) is called

However, this does not happen: all the dynamically generated views are not restored if I terminate and re-open the app.

The code follows:

PacketEditorFragment packetFragment = PacketEditorFragment.newInstance();
ViewGroup vg = (ViewGroup) findViewById(R.id.packetFragmentContainer);

LinearLayout linearLayout = new LinearLayout(this);

int layoutId = IDS++;
String fragmentTag = FRAGMENT_TAG + layoutId;

linearLayout.setId(layoutId);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);

vg.addView(linearLayout);

DeleteImageView deleteFragmentIV = new DeleteImageView(this, layoutId, fragmentTag);
deleteFragmentIV.setId(layoutId);
deleteFragmentIV.setOnClickListener(this);
deleteFragmentIV.setImageResource(R.mipmap.ic_delete);
linearLayout.addView(deleteFragmentIV);

getSupportFragmentManager().beginTransaction()
                .add(linearLayout.getId(), packetFragment, fragmentTag)
                .commit();

Is that piece of documentation valid also for Views that are generated dinamically?

There is another point which is a little obscure to me: What about the Fragment, that has not an ID (it is added using a String tag). Should I save and restore its state programmatically? The DeleteImageView stores a reference to a Fragment instance and deletes it in the OnClick listener method.

I have seen that there is way to restore a given instance of a fragment, but is it possible to have this behaviour for free? Even if they are generated dynamically, they are still part of the view hierarchy of the activity.

Antonio Sesto
  • 2,868
  • 5
  • 33
  • 51
  • did you try to assign R.id. something? – pskink Mar 10 '15 at 14:35
  • Do you mean to the fragment? – Antonio Sesto Mar 10 '15 at 14:42
  • no, i mean your Views, layout and image view – pskink Mar 10 '15 at 14:45
  • Sorry, but I do not understand what elements you are referring to. Besides those generated dynamically, whose ids are set programmatically (except for the `Fragment`), everything else has an id. – Antonio Sesto Mar 10 '15 at 14:54
  • your layout is created by you, right? set its id to R.id.simething – pskink Mar 10 '15 at 15:12
  • Any dynamically created views by configuration change will be vanished and this is irrespective of whether it had id or not. You should create them again in your `onCreate` or somewhere else. – frogatto Mar 10 '15 at 15:18
  • Is there any documentation I can read about this? The doc I cited does not speak about static/dynamic views, only about id. – Antonio Sesto Mar 10 '15 at 15:20
  • @AntonioSesto Do you exactly know what happens when a device rotates? – frogatto Mar 10 '15 at 15:23
  • I think I did, but your answer forced me to think 'may be not' (then an explanation concerning the doc I cited would be kind). Please notice I am not speaking about instance fields getting destroyed and causing bad accesses, but to components living in the view hierarchy. – Antonio Sesto Mar 10 '15 at 15:55
  • the code you posted: is it executed in onCreate? – pskink Mar 10 '15 at 16:06
  • @pskink No. The fragments contain optional data that the user is free to add or not. The static GUI contains a plus button: its onClickListener executes the code above. – Antonio Sesto Mar 10 '15 at 16:37
  • no wonder that you dont see your dynamically created linearLayout and deleteFragmentIV: how android could add them? – pskink Mar 10 '15 at 16:40
  • There's another container (FrameLayout) in the same XML layout containing one of two different fragments: the user decides. This container has no problems in remembering which fragment it was hosting at the time the app was killed: I did not add any specific code. This makes perfect sense according to the documentation. The problem is connected to elements that are not specified in the XML file: the doc only speaks about ID, it should work. – Antonio Sesto Mar 10 '15 at 16:52
  • when the device rotates you create the "normal static" views by calling setContentView but you don't add "dynamic" views: "linearLayout" and "deleteFragmentIV", that's why you don't see them – pskink Mar 10 '15 at 18:42

1 Answers1

0

Ok, I solved the problem after reading the accepted answer of this question Restoring view hierarchy from saved state does not restore views added programatically.

Basically, when the activity is restored, you need to add the views you added programmatically with the same ID they had the first time you created them.

This approach does not make any sense to me: starting from the static layout provided in the XML file the system has all the info needed to first re-create the layout the activity had when it was killed and then pass the saved Bundle to each component. However, this is the way it works: you need to re-create the layout and assign to each component the same ID it had.

Community
  • 1
  • 1
Antonio Sesto
  • 2,868
  • 5
  • 33
  • 51