Navigation Box + ViewPager + Fragments, ViewPager does not destroy nested fragments

My application has a navigation box with two elements: ViewPager (inside the fragment) and SupportMapFragment.

ViewPager uses the FragmentStatePagerAdapter and getItem(int position)returns two fragments.

When I open the navigation box and I select "item 1" (SupportMapFragment), another fragment (ViewPager inside) executes onDestroy() method, but this method does not destroy the fragments created by the adapter, so when I select "item 0" again, my application creates a ViewPager with its two elements and two other fragments that ViewPager did not delete.

This problem creates the sames fragment when selecting "item 1" and then "item 0" ... Thus, the number of fragments increases.

How does the ViewPager remove abstracts when its container fragment executes onDestroy?

My code

Mainactivity

public class Main extends SherlockFragmentActivity {

//Nombre de los elementos de la lista
private String[] mTitles;   
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private ListView mDrawerList;

private int currentPosition;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_navigation_drawer);

    //Inicialmente no hay ninguna opcion
    currentPosition = -1;

    mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
    mDrawerList = (ListView)findViewById(R.id.left_drawer);
    mDrawerToggle = new ActionBarDrawerToggle(
            this, 
            mDrawerLayout,
            R.drawable.ic_drawer, 
            R.string.drawer_open, 
            R.string.drawer_close) {

        /** Called when a drawer has settled in a completely closed state. */
        public void onDrawerClosed(View view) {
            // creates call to onPrepareOptionsMenu()
            supportInvalidateOptionsMenu();
        }

        /** Called when a drawer has settled in a completely open state. */
        public void onDrawerOpened(View drawerView) {             
            // creates call to onPrepareOptionsMenu()
            supportInvalidateOptionsMenu();
        }
    };

    mTitles = getResources().getStringArray(R.array.navigation_drawer_options);

    //Asignamos el Adapter
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,R.layout.drawer_list_item, mTitles));
    //Asignamos el listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

    if (savedInstanceState == null) {
        selectItem(0);
    }
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

private class DrawerItemClickListener implements ListView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}

/** Swaps fragments in the main content view */
private void selectItem(int position) {
    // Create a new fragment and specify the planet to show based on position

    if(currentPosition != position){
        //Solo hacemos remplazo de fragment si la opcion selecionada no es la misma
        //que la que esta ya en pantalla
        Fragment fragment = null;
        String fragmentName = "";
        boolean attach = true;

        switch (position) {
            case 0:
                fragmentName = PagerFragment.class.getSimpleName();
                fragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
                if(fragment == null) {
                    fragment = new PagerFragment();
                    attach = false;
                }
                break;
            case 1:
                fragmentName = Map1Fragment.class.getSimpleName();
                fragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
                if(fragment == null) {
                    fragment = new Map1Fragment();
                    attach = false;
                }
                break;      
            default:
                throw new IllegalArgumentException("Posicion no valida");
        }

        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        if(!attach){
            transaction.replace(R.id.content_frame, fragment);
        }else{
            transaction.attach(fragment);
        }
        transaction.commit();
    }
    currentPosition = position;
    // Highlight the selected item, update the title, and close the drawer
    mDrawerList.setItemChecked(position, true);     
    mDrawerLayout.closeDrawer(mDrawerList);
}

}

Snippet with ViewPager

public class PagerFragment extends SherlockFragment{

private ViewPager viewPager;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    Log.d("PagerFragment", "onCreateView");
    return inflater.inflate(R.layout.application_tus, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d("PagerFragment", "onViewCreated");
        viewPager = (ViewPager) view.findViewById(R.id.viewpager);
        viewPager.setAdapter(new ViewPagerAdapter(getSherlockActivity(), getFragmentManager()));

        TitlePageIndicator titleIndicator = (TitlePageIndicator)view.findViewById(R.id.titles_viewpager);
        titleIndicator.setViewPager(viewPager,0);

}
}

FragmentStatePagerAdapter

public class ViewPagerAdapter extends FragmentStatePagerAdapter{

public static final int NUM_PAGES = 2;
public static final int [] titles = { R.string.st1, R.string.st2};

private Context context;

public ViewPagerAdapter(Context context, FragmentManager fragmentManager) {
    super(fragmentManager);
    this.context = context;
}

@Override
public Fragment getItem(int position) {
    Log.d("ViewPagerAdapter", "GetItem(" + position+")");
    switch (position) {
        case 0:
            return new FavoritesFragment();         
        case 1:
            return new LinesFragment();     
        default:
            throw new IllegalArgumentException("Error");
    }
}

@Override
public int getCount() {
    return NUM_PAGES;
}

@Override
public CharSequence getPageTitle(int position) {
    return context.getString(titles[position]);
}

}
+2
source share
1 answer

I finally solved my problem.

When I create a FragmentStatePagerAdapter, I used new ViewPagerAdapter(getSherlockActivity(), getFragmentManager()). I finally used getChildFragmentManager()and it works!

+3
source

All Articles