Reputation: 3697
I have an activity which displays two fragments:
Fragment1
.Fragment1
, it displays Fragment2
, adding to backstack.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:
CheckBox
and type some text into EditText
Button
to launch Fragment2
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
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