1

I'm currently working with an application that has "swipey-tabs" and uses the following PagerAdapter:

public class TabsPagerAdapter extends FragmentPagerAdapter {

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


    @Override
    public Fragment getItem(int index) {
        switch (index) {
            case 0:
                return new HomeFragment();
            case 1:
                return new ListFragment();
            case 2:
                return new ChartFragment();
        }

        return null;
    }

    @Override
    public int getCount() {

        return 3;
    }

}

I'm using the following code to communicate with one of my fragments from the main activity:

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 1)
        {
            if (resultCode == Activity.RESULT_OK)
            {
                String className = data.getExtras().getString("class_name");
                if (className.trim().length() > 0) {
                    HomeFragment homeFrag = (HomeFragment) getSupportFragmentManager().findFragmentById(R.id.home_fragment);
                    if(homeFrag != null) {
                        Log.d("MainActivity", "homeFrag is not null");
                        homeFrag.newClass(className);
                    }else{
                        Log.d("MainActivity", "homeFrag is null");
                        HomeFragment newFragment = new HomeFragment();

                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.home_fragment, newFragment);
                        transaction.commit();
                        newFragment.newClass(className);
                    }
                    addSubjectToDataBase(className);
                }

            }
        }
    }

My problem is that when I try to communicate with the fragment from the main activity, I seem to get multiple fragments existing at the same time. When I change the orientation of the screen or restart the activity, I get the modified version of the fragment, but when I swipe back and forth to view the fragments, I get the old, non-modified version of the fragment. The fragment manager doesn't seem to be registering the fragments created by the adapter because though I know the fragments have been created, the fragment manager always returns a null home fragment.

How should I go about avoiding this problem, and what is the best way to communicate with the fragment from the main activity?

Matthias
  • 71
  • 1
  • 1
  • 7

2 Answers2

1

After reading through this post I worked out a solution to my own question. The problem was that since FragmentPagerAdapter manages its own fragments, the fragment that I was trying to access wasn't the same as the one being used by the view pager.

I worked out a way of accessing the tags of the fragments that are used by the view pager by modifying my modifying my PagerAdapter as such:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    protected String homeTag;
    protected String listTag;
    protected String chartTag;

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

    @Override
    public Fragment getItem(int index) {
        switch (index) {
            case 0:
                Log.d("Adapter", "returning new homeFragment");
                return new HomeFragment();
            case 1:
                return new ListFragment();
            case 2:
                return new ChartFragment();
        }

        return null;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment createdFragment = (Fragment) super.instantiateItem(container, position);

        switch (position){
            case 0:
                homeTag = createdFragment.getTag();
                break;
            case 1:
                listTag = createdFragment.getTag();
                break;
            case 2:
                chartTag = createdFragment.getTag();
                break;
        }

        return createdFragment;
    }

    public String getHomeTag(){
        return  homeTag;
    }

    public String getListTag(){
        return listTag;
    }

    public String getChartTag(){
        return chartTag;
    }
    @Override
    public int getCount() {

        return 3;
    }

}

Then, it was a simple matter to modify my code to access the correct fragments after I had access the proper fragment tags:

HomeFragment homeFrag = (HomeFragment) getSupportFragmentManager().findFragmentByTag(mAdapter.getHomeTag());
                    if(homeFrag != null) {
                        Log.d("MainActivity", "homeFrag is not null");
                        homeFrag.newClass(className);
                    }else{
                        Log.d("MainActivity", "homeFrag is null");
                        HomeFragment newFragment = new HomeFragment();

                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.pager, newFragment, madapter.get);
                        transaction.commit();
                        newFragment.newClass(className);
Community
  • 1
  • 1
Matthias
  • 71
  • 1
  • 1
  • 7
0

It's not elegant but I would do something like this (Maybe someone will post a better solution):

In a singleton, I'll put an array of fragment:

public static Fragment[] sShownFragments = new Fragment[3];

Then in the getItem() method:

if(SingletonClass.sShownFragments[index]!=null){
    return mFragments[index];
}

switch (index) {
        case 0:
            SingletonClass.sShownFragments[index] = new HomeFragment();
            break;
        case 1:
            SingletonClass.sShownFragments[index] = new ListFragment();
        case 2:
            SingletonClass.sShownFragments[index] = new ChartFragment();
        default:
            SingletonClass.sShownFragments[index] = new Fragment();
}
return SingletonClass.sShownFragments[index];

Then in the getCount(): return SingletonClass.sShownFragments.length();

Now in your onActivityResult():

 \\some code ...
 ((HomeFragment)SingletonClass.sShownFragments[0]).newClass(className);
 \\ some other code...
Jibbo
  • 442
  • 3
  • 13