1
votes

I'm trying to implement a two tabs and also have a navigation drawer. I'm able to do both separately but when I try to combine the two I run into problems. I originally had the code for creating my two tabs and the nav drawer inside my MainActivity which was a Fragment Activity at the time, but when it became clear that for me to have a Home option on the nav drawer I decided to refactor the code for tabs into a fragment with tabs that wold be then filled with two fragments as before.

On launching appears to be fine but when I click on the home option in the nav drawer the fragment in each tab seems to be stripped away and two more tabs are added each time I click on the option.

private void selectItem(int position) {
        Fragment fragment = new NullFragment();
        switch (position){
            case 0:
                fragment = new HomeFragment();
                break;
            case 1:
                         //Placeholder
                fragment = new PlanetFragment();

        }
        // update the main content by replacing fragments
        if (fragment != null) {
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

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

HomeFragment.java

public class HomeFragment extends Fragment implements ActionBar.TabListener {

    AppSectionsPagerAdapter appSectionsPagerAdapter;
    ViewPager viewPager;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View rootView = null;
        /*if(savedInstanceState == null){*/
        rootView = inflater.inflate(R.layout.activity_home, container, false);
        appSectionsPagerAdapter = new AppSectionsPagerAdapter(getFragmentManager());
        final ActionBar actionBar = getActivity().getActionBar();

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);


        viewPager = (ViewPager) rootView.findViewById(R.id.pager);
        viewPager.setAdapter(appSectionsPagerAdapter);
        viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

            actionBar.addTab(
                    actionBar.newTab()
                            .setIcon(R.drawable.ic_sync_to_cloud)
                            .setTabListener(this));

            actionBar.addTab(
                    actionBar.newTab()
                            .setIcon(R.drawable.ic_send_to_device)
                            .setTabListener(this));


            actionBar.setDisplayShowHomeEnabled(false);
            actionBar.setDisplayShowTitleEnabled(false);

        return rootView;
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in the ViewPager.
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }
}

I assume this is because a new instance of HomeFragment is created each time and the only thing in its layout is a ViewPager. Is there a way to do this so a new instance isn't created but instead the fragment can be stored and restored. Let me know if you need to see more code.

1

1 Answers

5
votes

I am doing a similar thing: I have a navigation drawer and one of the drawer items is a ViewPager with tabs. Everything worked fine when I opened the ViewPager tab the first time, but when I navigated back to it after navigating to one of the other tabs, it was empty and there were twice as many tabs (navigating to another activity and back was fine).

There are two issues here, one is that onCreate gets run again and adds your tabs again, resulting in duplicate tabs. You can fix this relatively easily by either checking for existence before adding them or by removing all tabs on destroy. I added this method in case other activities/fragments use other tabs (you'll also have to track the actionBar variable as a class variable instead of a method variable):

@Override
public void onDestroy() {
    actionBar.removeAllTabs();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    super.onDestroy();
}

The empty tabs appear to be due to different fragment managers not being able to locate the correct fragments. Check out the difference between using getSupportFragmentManager/getFragmentManager and getChildFragmentManager (What is difference between getSupportFragmentManager() and getChildFragmentManager()?).

The fix was to use getChildFragmentManager instead of getFragmentManager when initializing my PagerAdapter (your AppSectionsPagerAdapter) in the pager fragment.

appSectionsPagerAdapter = new AppSectionsPagerAdapter(getFragmentManager());

becomes

appSectionsPagerAdapter = new AppSectionsPagerAdapter(getChildFragmentManager());