Viewpager tabs recreated?

2019-06-01 20:46发布

问题:

I have implemented a NavigationDrawer with a few items in it. Every item represents a different Fragment and one of them has tabs. My problem is that every time I open this Fragment the tabs reloaded! and added to the previous tabs. Why is this happening and how can I solve it?

This is the Fragment with the tabs:

public class fragment_profilo_tabs extends Fragment implements ActionBar.TabListener {

    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    String[] tabs = { "Profilo aziendale", "Credenziali" };

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
     */
    @Override
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        // Initilization
                View view = View.inflate(getActivity(), R.layout.profilo_tabs, null);

                viewPager = (ViewPager) view.findViewById(R.id.pager);
                actionBar = getActivity().getActionBar();
                mAdapter = new TabsPagerAdapter(getFragmentManager());

                viewPager.setAdapter(mAdapter);
                actionBar.setHomeButtonEnabled(false);
                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

                // Adding Tabs
                for (String tab_name : tabs) {
                    actionBar.addTab(actionBar.newTab().setText(tab_name)
                            .setTabListener(this));}

        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
        return view;

    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }
}

And this is my ViewPagerAdapter:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    /* (non-Javadoc)
     * @see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object)
     */

    @Override
    public int getItemPosition(Object object) {
        // TODO Auto-generated method stub
         return POSITION_NONE;
    }

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new fragment_profilo_modificaProfilo();
        case 1:
            // Games fragment activity
            return new fragment_profilo_credenzialiAccesso();
        }
        return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 2;
    }

}

回答1:

Ok there are multiple issues. First and foremost lets talk about your ViewPagerAdapter:

The first thing that caught my eye is this:

@Override
public int getItemPosition(Object object) {
    // TODO Auto-generated method stub
     return POSITION_NONE;
}

This is very bad for performance. I know that some posts on Stack Overflow suggest using this to "fix" a few things, but that is not the way to go. Remove this, you don't need it.


But the main issue is in your Fragment. First and foremost this:

for (String tab_name : tabs) {
    actionBar.addTab(actionBar.newTab()
        .setText(tab_name)
        .setTabListener(this));
}

You are adding tabs to the ActionBar. And the ActionBar is not part of you Fragment. Each time you display this Fragment you add the same tabs to the ActionBar but you never remove them again or anything.

My advice: Don't do this. Open a new Activity for the tabs Fragment. This should clearly not be in the same Activity. I cannot imagine any situation where suddenly adding tabs to the current Activity would satisfy the Android Platform Guidelines or provide good usability.


The general rule is that everything that has to do with the Activity itself - like things concerning the ActionBar or tabs in the ActionBar - should be handled in the Activity. Code which adds tabs to the ActionBar has no place inside a Fragment. So either add the tabs permanently in onCreate() of your Activity. Or create a new Activity with those tabs especially for the fragment_profilo_tabs.

As an aside: class names should never be Snake Case. Start class names with an uppercase letter and use Camel Case. Everything else will just confuse other programmers looking at your code