问题
Hi i have a listview sidebar and i am displaying fragments based on user selection in listview.
This is how i am replacing fragments
public void switchFragment(Fragment fragment, boolean addBackStack) {
try {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
currentFragment = fragment;
//if (addBackStack)
ft.addToBackStack(null);
ft.commit();
} catch (Exception e) {
}
}
This is my sample fragment code.Now when i replace fragments i am saving instance state in onpause and restoring it in onresume but it only works when i press back button. When i manually navigate back to fragment from listview ,fragment state is not restored.Why?
public class Fragment1 extends BaseFragment {
int currentFragmentInd = 1;
private Button startButton;
private Button endButton;
private long savedStartTime;
private TextView setStartText;
private TextView setEndText;
private String starttime;
private String endtime;
public int getIndex() {
MyApplication.getApplication().setCurrentChild(0);
MyApplication.getApplication().setCurrentGroup(0);
return currentFragmentInd;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState !=null)
{
}
}
@Override
public void onResume() {
super.onResume();
setStartText= (TextView)getActivity().findViewById(R.id.MAtextView2);
setEndText= (TextView)getActivity().findViewById(R.id.MAtextView3);
setEndText.setText(endtime);
setStartText.setText(starttime);
}
@Override
public void onPause() {
super.onPause();
setStartText= (TextView)getActivity().findViewById(R.id.MAtextView2);
setEndText= (TextView)getActivity().findViewById(R.id.MAtextView3);
starttime=setStartText.getText().toString();
endtime=setEndText.getText().toString();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
FrameLayout frameLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.layout1, null, false);
((MainActivity) getActivity()).openList(0, 0);
if (savedInstanceState == null) {
}
startButton= (Button) contentView.findViewById(R.id.button);
endButton= (Button) contentView.findViewById(R.id.button2);
endButton.setEnabled(false);
setStartText= (TextView)contentView.findViewById(R.id.MAtextView2);
setEndText= (TextView)contentView.findViewById(R.id.MAtextView3);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Time now = new Time();
now.setToNow();
}
});
endButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Time now = new Time();
now.setToNow();
setEndText.setText(now.hour+" : "+now.minute);
}
});
return contentView;
}
}
回答1:
Late replay but might help somebody else. This happens because when you click a listview item you create a new inctance of that fragment. "I assume the fragment you send to switchFragment(Fragment fragment), is created using a 'new' keyword." Therefore this new instance of a fragment doesnt hold your old data.
This is how I solved this. There are probably better ways, but since nobody replied, I will give my solution.
- When you replace the fragment (ft.replace, fragment), give a string reference to that transaction: -ft.replace(R.id.content, fragment, "FRAGMENT_NAME");
- When you add the fragment to the backstack with addToBackStack(null); put the name of your fragment where you have null.: -ft.addToBackStack("FRAGMENT_NAME");
Create a method which tells you if that fragment has already been created, and therefore exists in the back stack.:
public boolean isTagInBackStack(String tag){Log.i(TAG, "isTagInBackStack() Start"); int x; boolean toReturn = false; int backStackCount = getSupportFragmentManager().getBackStackEntryCount(); Log.i(TAG, "backStackCount = " + backStackCount); for (x = 0; x < backStackCount; x++){ Log.i(TAG, "Iter = " + x +" "+ getSupportFragmentManager().getBackStackEntryAt(x).getName()); if (tag == getSupportFragmentManager().getBackStackEntryAt(x).getName()){ toReturn = true; } } Log.i(TAG, "isTagInBackStack() End, toReturn = " + toReturn); return toReturn; }Now before you create a new instance of that fragment check in the backstack if a backstack item named "FRAGMENT_NAME" exists. if it exists, use that item (fragment) instead of creating a new one.
if (isTagInBackStack("FRAGMENT_NAME")){ Log.i(TAG, "Tag is in BackStack!!!! frag is = " + getSupportFragmentManager().findFragmentByTag("FRAGMENT_NAME")); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.main_activity_container, getSupportFragmentManager().findFragmentByTag("FRAGMENT_NAME")); transaction.addToBackStack("FRAGMENT_NAME"); transaction.commit(); }else{ Create the fragment (this happens the first time. }
来源:https://stackoverflow.com/questions/22468977/android-fragment-state-restored-only-on-back-button-not-when-i-select-a-fragme