Is it possible to manually call onCreateView in a Fragment?
Asked Answered
L

3

24

Is it possible to manually call the method onCreateView in a Fragment or, if not, is there some way I can simulate this invocation?

I have a FragmentActivity with tabHost. Each tab contains a Fragment and I want to refresh the Fragment's view when I press the "Refresh" button. More specifically, I want to re-call the onCreateView method.

My code currently looks like:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
    view= inflater.inflate(R.layout.fragment_hall, container, false);

    layoutExsternal = (RelativeLayout) view.findViewById(R.id.layoutExsternal);
    layoutHall = (RelativeLayout) view.findViewById(R.id.layoutHall);

    init();

    return view;
 }

  [...]

@Override
public boolean onOptionsItemSelected(MenuItem item) {
      // TODO Auto-generated method stub
     Log.d("itemSelected1", this.getClass().getSimpleName());

     switch (item.getItemId()) {
        case R.id.menu_refresh:

            //HERE I want to insert a method for refresh o redraw

     return true;
     }

return super.onOptionsItemSelected(item);

}
Lapel answered 20/6, 2013 at 7:21 Comment(2)
A better approach would be to refactor your onCreateView. First find your layout views and assign them to fields, then call a delegate method that populates them. Then have your refresh action call the delegate. You seem to already have this with your init() method. Can't refresh just call that?Indeterminism
I find this approach useful https://mcmap.net/q/582489/-refresh-or-force-redraw-the-fragmentCam
L
9

I have resolved my question. I replace the current fragment with itself, but before I have saved a reference of current fragment and then i close life cycle of current fragment invoking onDestroy(). I recall it with "newFragment" variable.

         

     switch (item.getItemId()) {

        case R.id.menu_refresh:
         //THIS IS THE CODE TO REFRESH THE FRAGMENT.
             FragmentManager manager = getActivity().getSupportFragmentManager();
             FragmentTransaction ft = manager.beginTransaction();
             Fragment newFragment = this;
             this.onDestroy();
             ft.remove(this);
             ft.replace(container.getId(),newFragment);
              //container is the ViewGroup of current fragment
             ft.addToBackStack(null);   
             ft.commit();

        return true;
    }

Lapel answered 26/6, 2013 at 7:36 Comment(2)
Manually calling lifecycle methods is never the right solution. Also you don't need the newFragment variable; you could just use this again.Eusebioeusebius
As @Eusebioeusebius says, manually calling lifecycle methods is not a good approach.Germanize
P
35

Sometimes I found FragmentTransaction's replace would not work for replacing a fragment with itself, what does work for me is using detach and attach:

getSupportFragmentManager()
    .beginTransaction()
    .detach(fragment)
    .attach(fragment)
    .commit();

See this question for the difference between remove and detach

Paisa answered 16/10, 2013 at 16:55 Comment(2)
I used it in onActivityResult (coming back from settings where layout-affecting options may have changed) where I needed commitAllowingStateLoss because "You will receive this call immediately before onResume() when your activity is re-starting.". Calling commit would cause "Can not perform this action after onSaveInstanceState". Fragment state is still PRESERVED!Desjardins
Use .commitAllowingStateLoss() instead!Dung
L
9

I have resolved my question. I replace the current fragment with itself, but before I have saved a reference of current fragment and then i close life cycle of current fragment invoking onDestroy(). I recall it with "newFragment" variable.

         

     switch (item.getItemId()) {

        case R.id.menu_refresh:
         //THIS IS THE CODE TO REFRESH THE FRAGMENT.
             FragmentManager manager = getActivity().getSupportFragmentManager();
             FragmentTransaction ft = manager.beginTransaction();
             Fragment newFragment = this;
             this.onDestroy();
             ft.remove(this);
             ft.replace(container.getId(),newFragment);
              //container is the ViewGroup of current fragment
             ft.addToBackStack(null);   
             ft.commit();

        return true;
    }

Lapel answered 26/6, 2013 at 7:36 Comment(2)
Manually calling lifecycle methods is never the right solution. Also you don't need the newFragment variable; you could just use this again.Eusebioeusebius
As @Eusebioeusebius says, manually calling lifecycle methods is not a good approach.Germanize
O
3

You can just have your replace button replace the current layout with a new instance of the fragment.

// onButtonClick
SomeFragment fragment = new SomeFragment();
getFragmentManager().beginTransaction().replace(R.id.current_layout, fragment).commit();
Overwrite answered 24/6, 2013 at 20:56 Comment(1)
Isn't there a commit missing?Desjardins

© 2022 - 2024 — McMap. All rights reserved.