1
votes

UPDATE : I don't understand why when tapping on each tab onTabSelected() doesn't show the correct fragment even though it's been added to the fragmentTransaction android.R.id.content.
I call this method before onTabSelected gets called to make sure fragments are not null.

   protected void initTabs() {
                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                if(mShowFragment3 == null) {


                    mShowFragment3 = EpisodeTileFragment.newInstance(getString(R.string.title_section4));
                    ft.add(android.R.id.content, mShowFragment3);
                } 
                if(mShowFragment2 == null) {
                    mShowFragment2 = EpisodeTileFragment.newInstance(getString(R.string.title_section3));
                    ft.add(android.R.id.content, mShowFragment2);
                } 
}
    @Override
    public void onTabSelected(ActionBar.Tab tab,
            FragmentTransaction ft) {
    //this usually works, but if i try to mess with adding the tabs to the 
    //FragmentTransaction this won't work anymore
    if(tab.getPosition() == 1) {
       ft.show(mShowFragment2);
    }

I have scoured the internet and this may not be possible but I wanted to give this a shot.

I currently have the app working fine, it has 4 tabs and 4 corresponding fragments. When a user opens the app onTabSelected is called and selects the first tab/fragment is added and we're all good.

A user clicks tab2 and the 2nd fragment is added and rendered. When a user clicks the 2nd tab there is an asynctask that gets data and renders this on a fragment. Etc.. this happens on tab 3 and 4 also. When a user clicks a tab the first time I instantiate the fragment and add it to the fragmentTransaction, the next time you click on the tab it's lightning fast because it's already added, and I'm hiding and showing fragments.

The question I have is , is there a way to load up all 4 tabs at the same time, vs. waiting for a user to click on a tab and then have onTabSelected firing and grabbing data etc. Please let me know if there is any questions, the code is working with no errors just not what I want, and I don't know how to instantiate all 4 fragments at the same time.

mSectionsPagerAdapter = new SectionsPagerAdapter(this.getSupportFragmentManager());


        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {   
            LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
            View tabView = inflater.inflate(R.layout.tab_title, null);

            TextView titleTV = (TextView) tabView.findViewById(R.id.action_custom_title);
            titleTV.setText(mSectionsPagerAdapter.getPageTitle(i));
            titleTV.setTypeface(Typeface.createFromAsset(getAssets(), getString(R.string.tab_font)));
            titleTV.setSingleLine();
            titleTV.setTextSize(13);
            Tab t = actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))                 
                    .setTabListener(this);

            t.setCustomView(tabView);

            actionBar.addTab(t);
        }

this is for adding the tabs. but need to add the fragments for each tab.

1

1 Answers

0
votes

Set the offscreen page limit to your number of tabs, and then your ViewPager will render all the fragments when the parent activity is created.

mViewPager.setOffscreenPageLimit(4);

You should also check out the Class Overview of ViewPager, which has a really good example of using a custom FragmentPagerAdapter called TabsAdapter with a ViewPager (instead of using the ADT generated SectionsPagerAdapter). I added the code from the official Android docs below:

public class ActionBarTabsPager extends Activity {
    ViewPager mViewPager;
    TabsAdapter mTabsAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mViewPager = new ViewPager(this);
        mViewPager.setId(R.id.pager);
        setContentView(mViewPager);

        final ActionBar bar = getActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

        mTabsAdapter = new TabsAdapter(this, mViewPager);
        mTabsAdapter.addTab(bar.newTab().setText("Simple"),
                CountingFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText("List"),
                FragmentPagerSupport.ArrayListFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText("Cursor"),
                CursorFragment.class, null);

        if (savedInstanceState != null) {
            bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
    }

    /**
     * This is a helper class that implements the management of tabs and all
     * details of connecting a ViewPager with associated TabHost.  It relies on a
     * trick.  Normally a tab host has a simple API for supplying a View or
     * Intent that each tab will show.  This is not sufficient for switching
     * between pages.  So instead we make the content part of the tab host
     * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
     * view to show as the tab content.  It listens to changes in tabs, and takes
     * care of switch to the correct paged in the ViewPager whenever the selected
     * tab changes.
     */
    public static class TabsAdapter extends FragmentPagerAdapter
            implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
        private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

        static final class TabInfo {
            private final Class<?> clss;
            private final Bundle args;

            TabInfo(Class<?> _class, Bundle _args) {
                clss = _class;
                args = _args;
            }
        }

        public TabsAdapter(Activity activity, ViewPager pager) {
            super(activity.getFragmentManager());
            mContext = activity;
            mActionBar = activity.getActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }

        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
            TabInfo info = new TabInfo(clss, args);
            tab.setTag(info);
            tab.setTabListener(this);
            mTabs.add(info);
            mActionBar.addTab(tab);
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return mTabs.size();
        }

        @Override
        public Fragment getItem(int position) {
            TabInfo info = mTabs.get(position);
            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            mActionBar.setSelectedNavigationItem(position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            Object tag = tab.getTag();
            for (int i=0; i<mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
        }

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

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