Listview fragment is getting recreated on pressing backbutton

∥☆過路亽.° 提交于 2019-12-12 08:15:22

问题


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.

  1. 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);
    
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!