Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment's onDestroyView called but view is not being destroyed

The Android fragment lifecycle shows that when a fragment is added to the backstack and then removed/replaced, onDestroyView() is called, and later on, when the fragment returns to the layout from the backstack, onCreateView() is called.

From my understanding it means that the fragment's view is being destroyed and recreated. If the user has input text in an EditText in fragment A and goes to fragment B and then back to A, when the fragment comes back the EditText's contents will have been erased.

However, this is not happening in the following code; can anybody explain why? I have already verified that FragmentA's onDestroyView() is being called.

enter image description here

MainActivity.java

public class MainActivity extends FragmentActivity {

    private Fragment currentFragment = null;

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

        if (savedInstanceState == null) {
            addFragment(new FragmentA());
        }
    }

    public void setCurrentFragment(Fragment fragment) {
        this.currentFragment = fragment;
    }

    @Override
    public void onBackPressed() {
        if (currentFragment instanceof FragmentB) {
            getSupportFragmentManager().popBackStackImmediate();
        } else {
            super.onBackPressed();
        }
    }

    public void addFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).addToBackStack(null).commit();
        setCurrentFragment(fragment);
    }
}

FragmentA.java

public class FragmentA extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_a, container, false);

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

        Button button = (Button)view.findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentB fragmentB = new FragmentB();
                Bundle arguments = new Bundle();
                arguments.putString("text", editText.getText().toString());
                fragmentB.setArguments(arguments);
                ((MainActivity)getActivity()).addFragment(fragmentB);
            }
        });
        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("Tag", "FragmentA.onDestroyView() has been called.");
    }
}

FragmentB.java

public class FragmentB extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);
        TextView textView = (TextView)view.findViewById(R.id.textView);
        textView.setText(getArguments().getString("text"));
        return view;
    }
}

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.fragmenttest.MainActivity"
    tools:ignore="MergeRootFrame" />

fragment_a.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

</LinearLayout>

fragment_b.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
like image 593
Piovezan Avatar asked Feb 05 '15 13:02

Piovezan


People also ask

When fragment onDestroyView is called?

This answer is not useful. Show activity on this post. It seems to all depend on whether the fragment is retained or not. When the fragment is retained, then after onDestroyView comes onCreateView.

What is onDestroyView?

onDestroyView() allows the fragment to clean up resources associated with its View. onDestroy() called to do final cleanup of the fragment's state. onDetach() called immediately prior to the fragment no longer being associated with its activity.

What the fragment's method SetRetainInstance Boolean does?

SetRetainInstance(true) allows the fragment sort of survive. Its members will be retained during configuration change like rotation. But it still may be killed when the activity is killed in the background.


1 Answers

Fragments in back stack retain their state in a Bundle. This includes the view hierarchy state with the current contents of EditTexts and such.

like image 87
laalto Avatar answered Sep 16 '22 12:09

laalto