14

I'm currently utilizing the Navigation Drawer for my Android APP. In my first fragment, I've a fragment that loads data using Facebook's Graph API. Thus, when my App is first loaded, it first goes to the first fragment.

First

Then, I use the Navigation Drawer to click on another Fragment and view it.

Second Fragment

And then finally, I reuse the Navigation Drawer to proceed back to the first Fragment and view it.

First Fragment

My issue that I'm facing is, how do I proceed to utilize the Fragment that has been created once instead of re-creating it whenever the Navigation Drawer Item is selected. My code for the switching of the fragments are as shown below.

private void displayView(int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
    case 0:
        fragment = new SelectionFragment();
        break;
    case 1:
        fragment = new HomeFragment();
        break;
    case 2:
        fragment = new PhotosFragment();
        break;
    case 3:
        fragment = new CommunityFragment();
        break;
    case 4:
        fragment = new PagesFragment();
        break;
    case 5:
        fragment = new SplashFragment();
        break;
    default:
        break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

I noticed that there is indeed a "new" instance of the Fragment every time whenever the option is selected. How do I go about implementing the logic of creating the Fragment instance ONCE and reusing it, so that I do not have to continuously load the Fragment over and over again.

OrangeDog
  • 36,653
  • 12
  • 122
  • 207
Arvind Dinivra
  • 357
  • 1
  • 3
  • 14
  • Have you seen any particular way to replace the ArrayAdapter with a FragmentStatePagerAdapter? I was wondering about this same question, too, but haven't really seen anyone actually do it, and neither have I (I've been lazy to try, not because it was impossible.) – EpicPandaForce Jun 12 '14 at 14:37

4 Answers4

18

To anyone who encounters the same issue with me,I've managed to find a solution.

In the container frame,I've to define specific fragment views that I'll be utilizing as shown below.

Specific fragments

In each Fragment view,I've to "link" it with the actual Fragment itself as shown below via the "android:name" attribute.Do take note of the the path to the Fragment,example for in my case it's com.example.confesssionsrp.SelectionFragment.

<fragment
    android:id="@+id/selectionFragment"
    android:name="com.example.confessionsrp.SelectionFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

In the the MainActivity(or the Activity where we're viewing the fragments),create variables for each of the Fragments as shown below.

Variables

Following that,in the Oncreate of the MainActivity(or your specific Activity),initialize the various fragments as shown below.

OnCreate

Proceed onto creating a new Method called "ShowFragment" as shown below.

private void showFragment(int fragmentIndex, boolean addToBackStack) {
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    for (int i = 0; i < fragments.length; i++) {
        if (i == fragmentIndex) {
            transaction.show(fragments[i]);
            if (Session.getActiveSession().isClosed()) {
                mDrawerLayout
                        .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }
        } else {
            transaction.hide(fragments[i]);
        }
    }
    if (addToBackStack) {
        transaction.addToBackStack(null);
    }
    transaction.commit();
}

From then on in the switching of the fragments,manually call upon the "ShowFragment" method with the selected Fragment as shown below.

Show Fragment

Doing all of this overall,will not reset the Fragment each time we view it,and therefore is the solution to the answer.Thank you for anyone who has helped me so far :)!

Arvind Dinivra
  • 357
  • 1
  • 3
  • 14
0

I am using the following code:

@Override
public void onNavigationDrawerItemSelected(int position) {

    // update the main content by replacing fragments
    FragmentManager fragmentManager = getFragmentManager();
    if(position==0){// selection of tabs content
        fragmentManager
        .beginTransaction()
        .replace(R.id.container,
                SimulatorFragment.newInstance(position + 1)).commit();
    }else if(position==1){
        fragmentManager
        .beginTransaction()
        .replace(R.id.container,
                HudFragment.newInstance(position + 1)).commit();
    }else if(position==2){
        // Display the fragment as the main content.
        fragmentManager
        .beginTransaction()
        .replace(R.id.container, 
                SettingsBasicFragment.newInstance(position +1)).commit();
    }else{

    }
}

You can replace by a new instance the first time and store the fragment, if it is not null, then replace by the stored fragment.

The activity must implement NavigationDrawerFragment.NavigationDrawerCallbacks

The fragment constructor and newInstance methods look like this:

public final class HudFragment extends Fragment {
/**
 * The fragment argument representing the section number for this
 * fragment.
 */
private static final String ARG_SECTION_NUMBER = "section_number";

/**
 * Returns a new instance of this fragment for the given section number.
 * @param simulation 
 */
public static HudFragment newInstance(int sectionNumber) {  
    HudFragment fragment = new HudFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

public HudFragment() {
}

To switch fragments by code I use this method inside the NavigationDrawerFragment:

/**
 * Select a different section
 * @param position
 */
public void select(int position){
    selectItem(position);
}

private void selectItem(int position) {
    mCurrentSelectedPosition = position;
    if (mDrawerListView != null) {
        mDrawerListView.setItemChecked(position, true);
    }            
    if (mDrawerLayout != null) {
        mDrawerLayout.closeDrawer(mFragmentContainerView);
    }
    if (mCallbacks != null) {
        mCallbacks.onNavigationDrawerItemSelected(position);
    }
}
XaviGG
  • 171
  • 2
  • 19
  • Hey there,thank you for the help!I truly appreciate it.But I've found another and more simpler way to implement it.Thank you once again for the help buddy! :) – Arvind Dinivra Jun 13 '14 at 15:08
0

The second option is to start with the example of navigationDrawer that Android SDK offers. I selected that template of activity when creating the project and almost all the code of my previous answer is produced automatically.

If you want to keep the fragments after device rotation or similars it is a different thing, you need then to retain the fragments. If not, you just need to save the new instance of the fragment in a variable and check if it is null to create a new one or use the old one.

XaviGG
  • 171
  • 2
  • 19
0

In case someone want's a different approach to this: you could find the fragment on the stack:

// check if this fragment is on the backstack to avoid creating a new one
    Fragment foundFragment =  fragmentManager.findFragmentByTag("unique_fragment_tag");
    if (foundFragment != null) {
          fragmentManager.popBackStackImmediate("unique_fragment_tag", 0);
            return;
    }
aarcoraci
  • 201
  • 3
  • 9