5

I have a viewpager in a fragment in which i am showing 3 fragments but when I open the fragment first time it opens fine and when I move to another fragment and came back to the viewpager fragment it doesn't show the fragments in view pager then I have to either change the orientation of the phone or keep swiping the viewpager for the hidden fragments to show.

I have googled it and now I know I have to set the tag to each fragment and retrieve fragment with findfragmentbytag method but problem is when I try to set the tag to fragment

getSupportFragmentManager().beginTransaction().add(myFragment, "Some Tag").commit();

above line crashes my app and logcat shows "cant set tag to fragment", I know I'm doing some stupid mistake

this is the complete code of my fragment. I would really appreciate if one could guide me where to write the code for setting the tag of fragments. thanks in advance.

public class MatchesListingFragment extends Fragment implements ActionBar.TabListener {

    Context context;
    SectionsPagerAdapter mSectionsPagerAdapter;
    ViewPager mViewPager;
    ActionBar actionBar;
    Matchlistings db;
    Bundle savedInstanceState;

    Fragment livescore,fixture,results;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        this.savedInstanceState = savedInstanceState;
        db = new Matchlistings(getActivity());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_matches, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        context = getActivity().getApplicationContext();

        if(savedInstanceState == null){
            livescore = new LiveScoreListingFragment();
            fixture = new FixturesListingFragment();
            results = new ResultsListingFragment();
        }

        if(!Constants.is_listing_refreshed){
            Log.i(MainActivity.TAG,"refreshing list");
            db.loadListingsFromServer().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        actionBar = getActivity().getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        if(mSectionsPagerAdapter == null)
        mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity().getSupportFragmentManager());
        mViewPager = (ViewPager) getView().findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });


        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            Tab tb = actionBar.newTab()
            .setText(mSectionsPagerAdapter.getPageTitle(i))
            .setTabListener(this);

            actionBar.addTab(tb);

        }
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {
        Fragment fragment;

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

        @Override
        public Fragment getItem(int position) {
            switch(position){
            case 0:

                fragment = livescore;
                return fragment;
            case 1:
                fragment = fixture;
                return fragment;
            case 2:
                fragment = results;
                return fragment;
            case 3:
                fragment = new LiveScoreListingFragment();
                return fragment;
            }
            return null;
        }

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

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
            case 0:
                return "LIVE";
            case 1:
                return "FIXTURES";
            case 2:
                return "RESULTS";
            case 3:
                return "HOT";
            }
            return null;
        }
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        actionBar.removeAllTabs();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    }

    @Override
    public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

}

enter image description here

EDIT: i have now tried to get the fragment from viewpager by tag instead of creating new fragment everytime. but problem is still same.

FixturesListingFragment fixture = (FixturesListingFragment) getActivity().getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.pager+":1");
                if(fixture == null)
                    fixture = new FixturesListingFragment();
Wasif Khalil
  • 2,217
  • 9
  • 33
  • 58

4 Answers4

12

Have you tried to use setOffscreenPageLimit? if you have 3 pages then set it to 2. This way pages won't be recreated even if the app is on iddle state. Here is the link

Angmar
  • 599
  • 4
  • 9
  • use it after you set the adapter, the number of pages is 4, you should set it the offscreen page limit to 3 then. – Angmar Jan 30 '14 at 10:19
  • mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setOffscreenPageLimit(3); i did this and im still getting pullpointer im updating the ques to show the screen shot... – Wasif Khalil Jan 30 '14 at 11:51
  • May I ask why do you return null in getItem? you should cover all cases, add a default case to avoid that but don't return null, it will crash. If it loads the default fragment then put less offscreenpages. – Angmar Jan 30 '14 at 12:24
  • thanks ill fix that... but the again my prob was not solved :-/ – Wasif Khalil Jan 31 '14 at 05:02
  • But why do you need to "get" those fragments? If there is a problem in fragment creation you should see if your layout is designed correctly. If you're trying to implement action bar tabs with a swipe gesture you should follow this [link](http://developer.android.com/training/implementing-navigation/lateral.html) – Angmar Jan 31 '14 at 11:04
  • 1
    hey @angmar thanks bro ihave fixed it by changing FragmentPagerAdapter to FragmentStatePagerAdapter... cant believe it was such a small issue... :D thanks bro! – Wasif Khalil Jan 31 '14 at 12:10
  • 1
    and this is what fixed my issue..../** * The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the * three primary sections of the app. We use a {@link android.support.v4.app.FragmentPagerAdapter} * derivative, which will keep every loaded fragment in memory. If this becomes too memory * intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}. */ – Wasif Khalil Jan 31 '14 at 12:10
  • Great, good thing that you could solve that. I didn't notice that you where using the FragmentPagerAdapter and not the FragmentStatePagerAdapter but it's true that in this case it's a better choice. – Angmar Feb 03 '14 at 10:28
5

I Have solved thiw problem by just using setOffScreenpageLimit(int) to the number of additional tabs that I have.

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new FragmentHome(), "Home");
    adapter.addFragment(new FragmentEProfile(), "e-Profile");
    adapter.addFragment(new FragmentResults(), "Results");
    adapter.addFragment(new FragmentOutpass(), "Outpass");
    viewPager.setAdapter(adapter);
    viewPager.setOffscreenPageLimit(3);
}
Sandeep Samudrala
  • 123
  • 1
  • 2
  • 12
4

i have fixed the issue by changing FragmentPagerAdapter to FragmentStatePagerAdapter... this is what i read in the sample app downloaded from this link

/**
     * The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the
     * three primary sections of the app. We use a {@link android.support.v4.app.FragmentPagerAdapter}
     * derivative, which will keep every loaded fragment in memory. If this becomes too memory
     * intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */

and changed it.. but still wondering there should be a way to do it with FragmentPagerAdapter

Wasif Khalil
  • 2,217
  • 9
  • 33
  • 58
0

Try to retain the instance as mentioned below:

 @Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    //add this line
    setRetainInstance(true);

    context = getActivity().getApplicationContext();
Mehul Joisar
  • 15,348
  • 6
  • 48
  • 57