5

in my program i have some Fragments and i can replace each Fragment by click on that with this code. my problem is this: those fragments are low to load and after click on each Fragments create new from it and cause of load again after clicked on fragment. how to save fragment content or state and prevent to reload?

@Override
    public void onNavigationDrawerItemSelected(int position) {
        Fragment fragment = null;
        switch (position) {
            case 0:
                fragment = new InfoFragment();
                break;
            case 1:
                fragment = new ParentOtoFragment();
                break;
            case 2:
                fragment = new ParentProFragment();
                break;
            case 3:
                fragment = new SupportFragment();
                break;
            case 4:
                fragment = new AboutFragment();
                break;
        }
        if (fragment != null){
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.container,fragment).commit();
        }
    }

POST UPDATE

after reply to this topic by @Vikram Ezhil i'm initials fragments and fragmentTAG into constructor and change @Vikram Ezhil code to this below code, my problem is solved.

@Override
   public void onNavigationDrawerItemSelected(int position) {
       FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
       fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

       if (getSupportFragmentManager().findFragmentByTag(fragmentTAGS[position]) == null) {
           fragmentTransaction.add(R.id.container, fragments[position], fragmentTAGS[position]);
       }
       for (int i = 0; i < fragments.length; i++) {
           if (i == position) {
               fragmentTransaction.show(fragments[i]);
           } else {
               if (getSupportFragmentManager().findFragmentByTag(fragmentTAGS[position]) != null) {
                   fragmentTransaction.hide(fragments[i]);
               }
           }
       }
       fragmentTransaction.commit();
   }
arslancharyev31
  • 1,801
  • 3
  • 21
  • 39

2 Answers2

6

To prevent the fragments from re-creating from scratch every time you click on an item from the navigation drawer you need to use

fragmentTransaction.add(R.id.container,fragment).commit();

instead of

fragmentTransaction.replace(R.id.container,fragment).commit();

However some extra bit of work is required when you add fragments instead of replacing them.

  1. You need to make sure the the same fragment is not added more than once. You can place a fragment TAG and check if the TAG exists before adding a fragment. Example,

    if (getFragmentManager().findFragmentByTag("fragment1_tag") == null)
    {
        fragmentTransaction.add(R.id.container, fragment1, "fragment1_tag");
    }
    
  2. You need to hide the fragments which are not shown, since when you start adding fragments they will be overlapping with each other on screen.

    if (getFragmentManager().findFragmentByTag("fragment1_tag") != null)
    {
        fragmentTransaction.hide(fragment1);
    }
    
  3. Use interface methods whenever you want to update a specific part in a fragment. I will not go in depth into this, since this is altogether a different topic.

  4. Make sure your fragments are not over-lapped once the application is killed by the android OS to allocate memory for other apps (check out this post for more info).

Also adding some suggestions - from your above code, you are having only one fragment variable and re-using it for all the 5 screens. I would recommend you to have separate fragment variable for the 5 screens and save it an array.

The reason being this would be far more easier and generic to control when you start adding, hiding, showing fragments. Example,

InfoFragment fragment1 = new InfoFragment();
ParentOtoFragment fragment2 = new ParentOtoFragment();
ParentProFragment fragment3 = new ParentProFragment();
SupportFragment fragment4 = new SupportFragment();
AboutFragment fragment5 = new AboutFragment();

Fragment[] fragments = new Fragment[]{fragment1,fragment2,fragment3,fragment4,fragment5};
String[] fragmentTAGS = new String[]{"fragment1_tag","fragment2_tag","fragment3_tag","fragment4_tag","fragment5_tag"};

Now using the above, you can switch between fragments based on the item clicked from your navigation drawer.

@Override
public void onNavigationDrawerItemSelected(int position) 
{
      // Add the fragments only once if array haven't fragment
      if (getFragmentManager().findFragmentByTag(fragmentTAGS[position]) == null)
      {
          fragmentTransaction.add(R.id.container,fragments[position],fragmentTAGS[position]);
      };

      // Hiding & Showing fragments
      for(int catx=0;catx<fragments.length;catx++)
      {
         if(catx == position)
         {
              fragmentTransaction.show(fragments[catx]);
         }
         else
         {
              // Check if the fragment is added and then hide it
              if (getFragmentManager().findFragmentByTag(fragmentTAGS[catx]) != null)
              {
                  fragmentTransaction.hide(fragments[catx]);
              };
         };
      };

      fragmentTransaction.commit();
};
Community
  • 1
  • 1
Vikram Ezhil
  • 995
  • 1
  • 9
  • 15
-1

Based on the previous answer i developed the following solution, hope it helps someone:

1.Declare an array with all your fragments:

private Fragment[] fragments = new Fragment[] { new frag1(), new frag2()};

2.When onNavigationItemSelected fires an event:

        Fragment fragment = null;
        switch (itemId) {
            case R.id.nav_frag1:
                fragment = fragments[0];
                break;
            case R.id.nav_frag2:
                fragment = fragments[1];
                break;
            default:
                return;
        }

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.content_main, fragment);
        ft.commit();
Liviu Mihaianu
  • 289
  • 3
  • 13