StenaviN
StenaviN

Reputation: 3697

Fragment loses its state when rotate device twice

I have an activity which displays two fragments:

Fragments are straightforward. Fragment1 contains CheckBox and EditText. Fragment2 contains simple TextView. Also I call setRetainInstance(true) in fragment's onCreate(...) method.

Problem: Fragment1 loses its state if Fragment2 is displayed and device is rotated twice. However, everything works as expected if device is rotate only once.

Steps to reproduce:

  1. Launch application.
  2. Check CheckBox and type some text into EditText
  3. Press Button to launch Fragment2
  4. Rotate device
  5. Rotate device once again
  6. Press Back button on your device (or ESC on Emulator) to return back to Fragment1

Fragment1 lost its state (checkbox is unchecked and EditText is empty). However, if you return back to Fragment1 after step#4 - Fragment1 keeps its state as expected.

Where is the problem? All code is below, including layouts.

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/placeholder"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

fragment1.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox" />

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

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Fragment2" />

</LinearLayout>

fragment2.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment #2" />

</LinearLayout>

FragmentTestActivity.java:

package fragmenttest.example.com;

import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;

public class FragmentTestActivity extends Activity implements FragmentListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        FragmentManager fm = getFragmentManager();
        if (fm.findFragmentByTag(Fragment1.TAG) == null) {
            fm.beginTransaction().replace(R.id.placeholder, new Fragment1(), Fragment1.TAG).commit();
        }
    }

    @Override
    public void onButtonClick() {
        FragmentManager fm = getFragmentManager();
        if (fm.findFragmentByTag(Fragment2.TAG) == null) {
            fm.beginTransaction().replace(R.id.placeholder, new Fragment2(), Fragment2.TAG).addToBackStack(Fragment2.TAG).commit();
        }
    }
}

Fragment1.java:

package fragmenttest.example.com;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class Fragment1 extends Fragment {
    public static final String TAG = Fragment1.class.getName();
    private FragmentListener mListener;

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment1, container, false);

        Button button = (Button) root.findViewById(R.id.button1);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.onButtonClick();
            }
        });

        return root;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        mListener = (FragmentListener) activity;
    }
}

Fragment2.java:

package fragmenttest.example.com;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment2 extends Fragment {
    public static final String TAG = Fragment2.class.getName();

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment2, container, false);
        return root;
    }
}

FragmentListener.java:

package fragmenttest.example.com;

public interface FragmentListener {
    public void onButtonClick();
}

Upvotes: 5

Views: 2187

Answers (1)

user433825
user433825

Reputation:

It may be because onCreate isn't called when restoring the fragment. See:http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)

Upvotes: 2

Related Questions