<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fragment &#8211; Pauls Blog</title>
	<atom:link href="https://sterl.org/tag/fragment/feed/" rel="self" type="application/rss+xml" />
	<link>https://sterl.org</link>
	<description></description>
	<lastBuildDate>Fri, 20 Sep 2019 13:13:35 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Android Fragments and Transactions</title>
		<link>https://sterl.org/2016/10/android-fragments-and-transactions/</link>
					<comments>https://sterl.org/2016/10/android-fragments-and-transactions/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Fri, 21 Oct 2016 08:51:01 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Fragment]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">http://sterl.org/?p=183</guid>

					<description><![CDATA[Problem Sometimes it is confusing how fragments work in Android and interesting side effects like: Why have Fragments empty constructors? Why shouldn&#8217;t I pass state variables like they are? Why do I need this Fragment transactions? What does addToBackStack mean and do I need it? Why is sometimes the Activity null in my fragment? Overview&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem </h2>



<p>Sometimes it is confusing how fragments work in Android and interesting side effects like: </p>



<ul class="wp-block-list"><li>Why have Fragments empty constructors?</li><li>Why shouldn&#8217;t I pass state variables like they are?</li><li>Why do I need this Fragment transactions?</li><li>What does addToBackStack mean and do I need it?</li><li>Why is sometimes the Activity <code>null</code> in my fragment? </li></ul>



<h2 class="wp-block-heading">Overview</h2>



<p>Fragments are used to wrap functionality into an own reusable UI element. The life cycle is well documented by <a href="https://developer.android.com/guide/components/fragments.html">google</a>. More interesting is, that android may recreate fragments during its life cycle which leads to interesting implications.</p>



<p>Furthermore Fragments are not directly added an visible, as requesting them to show only queues this task. Nevertheless, they will be shown later on.</p>



<p>Sometimes it is also confusing that creating a fragment inside a fragment will always pass the common activity of both fragments into it.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-eclipse" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Override
public void onAttach(Context context) {
    super.onAttach(context); // context is always the activity
}</pre></div>



<h3 class="wp-block-heading">Dynamic recreation</h3>



<p>As android can recreate the fragment during the resume process of an activity. As so state in member variables needs to be persisted. In general, fragments should always be created using a bundle or be dismissed by the activity in the onPause method: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-eclipse" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">public class MyDialogFragment extends DialogFragment {
    private static final String ARG_PARAM1 = &quot;param1&quot;;
    private String mParam1;

    public MyDialogFragment() {} // required

    // Create fragment with call parameters
    public static MyDialogFragment newInstance(String param1) {
        MyDialogFragment fragment = new MyDialogFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        fragment.setArguments(args);
        return fragment;
    }
    // restore any initial passed arguments as needed
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
        }
    }
    // if the param may change during the life cycle of the fragment and need to be stored
    // usually not needed
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(ARG_PARAM1, mParam1);
    }
}</pre></div>



<p>As long as the fragment is restored, the activity of it may be null. As so it may happen that own threads still running in the fragment may encounter null pointer exceptions.</p>



<p>The easiest way is either: </p>



<ul class="wp-block-list"><li>Stop all running threads in the onPause</li><li>Remove all listeners for the time being, but keep the threads, e.g. if you want to keep a socket connection open</li><li>save in a boolean variable the fact that your fragment was paused and wait for the resume </li></ul>



<h3 class="wp-block-heading">Hide and show DialogFragments</h3>



<p>Showing a fragment is straight forward, by calling the show method. Now we can pass a second parameter, which is used to find this fragment later on. We can decide by storing the reference in a field variable or just to remember the name. Usually the last is the better approach. </p>



<p>But how now correctly to dismiss the fragment? </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-eclipse" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">// show a fragment
MyDialogFragment dialogFragment = MyDialogFragment.newInstance(&quot;init&quot;);
dialogFragment.show(getFragmentManager(), &quot;dialog&quot;);

// hide a fragment again
Fragment dialog = getFragmentManager().findFragmentByTag(&quot;dialog&quot;);
if (dialog != null) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.remove(dialog);
    ft.commit();
}</pre></div>



<p>The above code example works for any kind of fragment. Of course, it is also possible to cast the fragment into a DialogFragment and invoke the dismiss method. </p>



<h3 class="wp-block-heading">addToBackStack or not?</h3>



<p>The main purpose of the <code>addToBackStack</code> method in the fragment transaction is to allow the user to use consistently the back button. If we modify the code above to: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-eclipse" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">Fragment dialog = getFragmentManager().findFragmentByTag(&quot;dialog&quot;);
if (dialog != null) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.remove(dialog);
    ft.addToBackStack(null); // remember this change
    ft.commit();
}</pre></div>



<p>Then the user may open the dialog again with the back button on the phone. This is very interesting if you move between different fragments/dialog fragments. E.g.: you have an edit dialog fragment which opens a date time picker dialog. Then you can remove the detail dialog fragment and add the date picker fragment in one transaction. As soon the user hits the back button the detail dialog fragment is again visible.</p>



<p>As the name already indicated, it is a stack of view states, each change to the view is seen as a transaction. The user may pop the stack by using the back button.</p>



<p><strong>In short:</strong></p>



<ul class="wp-block-list"><li>Cancel or just close the dialog/fragment &#8211;> don&#8217;t add it to the back stack</li><li>Navigate to a Fragment like to an activity &#8211;> add it to the back stack, so the user can go back </li></ul>



<h3 class="wp-block-heading">Prevent closing of a Dialog Fragment using the back button</h3>



<p>After the fragment was created set cancelable to false. </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-eclipse" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">dialogFragment.setCancelable(false);</pre></div>



<h2 class="wp-block-heading"> Is isVisible or isAdded reliable? </h2>



<p>This happens to be the most tricky question. As showing a dialog will not always show the dialog immediately. It only schedules the show operation for the Fragment Manager. </p>



<p>As soon as you happen to see errors like: </p>



<pre >
java.lang.IllegalStateException: Fragment already added: XxxxxDialog{xxx XxxxxDialog}
       at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1236)
       at android.app.BackStackRecord.run(BackStackRecord.java:715)
       at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1552)
       at android.app.FragmentManagerImpl$1.run(FragmentManager.java:487)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
</pre>



<p>The first solution by just calling <code>getFragmentManager().executePendingTransactions()</code>&nbsp;won&#8217;t&nbsp;work.</p>



<p>The reason is typically a multithreading issue, calling/ scheduling multiple show operations for the same fragment from a background thread. The best fix would be to find why this is called multiple times and check if this can be avoided. If not, then an AtomicBoolean could be the rescue e.g.:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-eclipse" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">public class MyDialog extends DialogFragment {
    private final AtomicBoolean isShowing = new AtomicBoolean(false);

    @Override
    public void show(FragmentManager manager, String tag) {
        isShowing.set(true); // ensure we update our &quot;show&quot; flag
        super.show(manager, tag);
    }

    @Override
    public void onResume() {
        super.onResume();
        isShowing.set(true);
    }
    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        isShowing.set(false);
    }
    /**
     * reader for the boolean flag, if show was already called
     */
    public boolean getIsShowing() {
        return isShowing.get();
    }
}</pre></div>



<p>Using the AtomicBoolean enables you now to verify in a multithreaded environment if <code>show</code> was already called on the dialog. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2016/10/android-fragments-and-transactions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
