问题
I'm using loader in my ListView fragment, and it's getting recreated on pressing "back" button. Can you tell me how to handle this senario?
Here is my ListView fragment code. Here I have a boolean variable that I'm setting as true on clicking on list item. but once the back button is pressed onCreateView will get called so the backbutton will be false.
public class GTFragment extends SherlockFragment implements LoaderCallbacks<Cursor>{
ListView mTListview = null;
GoogleTasksAdapter mGTasksAdapter = null;
private SQLiteCursorLoader mTLoader=null;
private LoaderManager mTLoaderManager;
private String mSelectedListID = null;
private boolean mIsBackbuttonisPressed = false;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.task_home_activity, container, false);
if(!mIsBackbuttonisPressed)
getLoaderManager().initLoader(0, null, this);
mTListview = (ListView) view.findViewById(R.id.id_task_list_home_activity);
mGTasksAdapter = new GoogleTasksAdapter(getActivity());
mTListview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> listview,
View clickedview, int position, long arg3) {
// TODO Auto-generated method stub
GoogleTaskItem item = new GoogleTaskItem();
Cursor coursor = ((GoogleTasksAdapter)listview.getAdapter()).getCursor();
if(coursor.moveToPosition(position))
{
mIsBackbuttonisPressed = true;
GoogleTaskController.get_googletask_controllerObj()
.LaunchTaskPreviewActivity();
}
}
});
mTListview.setAdapter(mGTasksAdapter);
mIsBackbuttonisPressed = false;
return view;
}
My fragment activity class code
public class TLActivity extends SherlockFragmentActivity {
LeftSliderTaskListOptions mTaskOptionsFragment = null;
GoogleTasksFragment mTFragment = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
setContentView(R.layout.layout_gt_list);
// FragmentTransaction tfragment = this.getSupportFragmentManager().beginTransaction();
mTFragment = new GTasksFragment();
t.replace(R.id.id_tfragment, mTFragment);
t.commit();
}
回答1:
You have multiple options to rectify this issue.
Override onSaveInstanceState like this:
@Override public void onSaveInstanceState (Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("mIsBackbuttonisPressed", mIsBackbuttonisPressed); }and then in your onCreateView you can get your variable back by:
if (savedInstanceState != null) mIsBackbuttonisPressed = savedInstanceState.getBoolean("mIsBackbuttonisPressed", false);You can set
this.setRetainInstance(true);in your onCreate method of your fragment.
If you could post your Activity code with creates your fragment I can also tell you other options. (P.S I cannot write it as a comment so posting it in the answer.)
回答2:
instead of
t.replace(R.id.id_tfragment, mTFragment);
use
t.add(R.id.id_tfragment, mTFragment);
It worked for me
回答3:
I don't think that the accepted answer is right because Fragment.onSaveInstanceState will not be called until the activity hosting it needs to save its state: The docs states:
There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state.
In other words: if you're using a Activity with multiple fragments for each screen (which is very common), the fragment state will not be saved when you move the next screen.
You also can't use Fragment.setRetainInstance because he's meant only to fragments that aren't on the back stack.
Most of the time, you don't have to think about this but sometimes it's important. Like when you have scrolled a list and want to "remember" the scroll location.
I took a long time to realize that the fragments put on the back stack are kind of saved and you can reuse the view that you already created instead of creating one every time the fragment calls onCreateView. My setup is something like this:
public abstract class BaseFragment extends Fragment {
private boolean mSaveView = false;
private SoftReference<View> mViewReference;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mSaveView) {
if (mViewReference != null) {
final View savedView = mViewReference.get();
if (savedView != null) {
if (savedView.getParent() != null) {
((ViewGroup) savedView.getParent()).removeView(savedView);
return savedView;
}
}
}
}
final View view = inflater.inflate(getFragmentResource(), container, false);
mViewReference = new SoftReference<View>(view);
return view;
}
protected void setSaveView(boolean value) {
mSaveView = value;
}
}
public class MyFragment extends BaseFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setSaveView(true);
final View view = super.onCreateView(inflater, container, savedInstanceState);
ListView placesList = (ListView) view.findViewById(R.id.places_list);
if (placesList.getAdapter() == null) { // this check is important so you don't restart your adapter
placesList.setAdapter(createAdapter());
}
}
}
来源:https://stackoverflow.com/questions/22589464/listview-fragment-is-getting-recreated-on-pressing-backbutton