Note that there are some explanatory texts on larger screens.

plurals
  1. POOnce for all, how to correctly save instance state of Fragments in back stack?
    text
    copied!<p>I have found many instances of a similar question on SO but no answer unfortunately meets my requirements.</p> <p>I have different layouts for portrait and landscape and I am using back stack, which both prevents me from using <code>setRetainState()</code> and tricks using configuration change routines.</p> <p>I show certain information to the user in TextViews, which do not get saved in the default handler. When writing my application solely using Activities, the following worked well:</p> <pre><code>TextView vstup; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.whatever); vstup = (TextView)findViewById(R.id.whatever); /* (...) */ } @Override public void onSaveInstanceState(Bundle state) { super.onSaveInstanceState(state); state.putCharSequence(App.VSTUP, vstup.getText()); } @Override public void onRestoreInstanceState(Bundle state) { super.onRestoreInstanceState(state); vstup.setText(state.getCharSequence(App.VSTUP)); } </code></pre> <p>With <code>Fragment</code>s, this works only in very specific situations. Specifically, what breaks horribly is replacing a fragment, putting it in the back stack and then rotating the screen while the new fragment is shown. From what I understood, the old fragment does not receive a call to <code>onSaveInstanceState()</code> when being replaced but stays somehow linked to the <code>Activity</code> and this method is called later when its <code>View</code> does not exist anymore, so looking for any of my <code>TextView</code>s results into a <code>NullPointerException</code>.</p> <p>Also, I found that keeping the reference to my <code>TextViews</code> is not a good idea with <code>Fragment</code>s, even if it was OK with <code>Activity</code>'s. In that case, <code>onSaveInstanceState()</code> actually saves the state but the problem reappears if I rotate the screen <em>twice</em> when the fragment is hidden, as its <code>onCreateView()</code> does not get called in the new instance.</p> <p>I thought of saving the state in <code>onDestroyView()</code> into some <code>Bundle</code>-type class member element (it's actually more data, not just one <code>TextView</code>) and saving <em>that</em> in <code>onSaveInstanceState()</code> but there are other drawbacks. Primarily, if the fragment <em>is</em> currently shown, the order of calling the two functions is reversed, so I'd need to account for two different situations. There must be a cleaner and correct solution!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload