1

I have an FragmentActivity that has tabbed fragments using the example adapter set forth in FragmentTabsPager.java (found in the Android Support v4 samples)

private static class TabsAdapter extends FragmentPagerAdapter
        implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {

I have a menu entry in my FragmentActivity that will let me reload the data inside the fragments at will. Before I implemented the tab interface, I could guarantee that the needed fragment would be loaded in memory. I'd get the Fragment via getSupportFragmentManager().findFragmentById(), cast it, then call its reload function. Simple enough.

Is there a way I can communicate with a specific Fragment instance loaded via FragmentPagerAdapter from a FragmentActivity? Using TabAdapter's getItem() provided in the sample, I can retreive a new instance (via Fragment.instantiate()) of my Fragment but not a reference to the one that's currently displayed. That's the one that matters.

EDIT: In addition to Plato's answer...
Since all my tabs are of different classes (eg. FooFragment, BarFragment, etc) it's very useful to identify and retrieve an active fragment of a specific type.

Object getActiveFragmentOfType(Class<?> cls) {
    List<Fragment> frags = getActiveFragments();
    for(Fragment one : frags) {
        if(cls.isInstance(one)) {
            return one;
        }
    }
    return null;
}

Then when I want to work on a specific tab/fragment/class I just do something like this

Object fooFragmentObject = getActiveFragmentOfType(FooFragment.class);
if(fooFragmentObject != null) {
    // Do something with an active reference to fooFragmentObject that's
    // guaranteed to be castable to FooFragment
}
Kevin Mark
  • 1,671
  • 1
  • 21
  • 49

1 Answers1

1

Use a base class for your fragments so you can add methods to save and get the position the fragment is used for. (You can do this with an interface which all would implement if you dont want them all to extends the same class)

So your fragment class would be something like this.

    class MyFragment extends SomeFragment{
       public void setPosition(int position){...}
       public int getPosition(){...}
       ......
    }

in your FragmentPagerAdapter edit the getItem() method to save the position within each fragment when you create it.

    @Override
    public Fragment getItem(int position) {
        MyFragment fragment = new MyFragment();
        //save the position when you create the Fragment
        fragment.setPosition(position);
        return fragment;
    }

Then implement a getActiveFragments() method as described here

After that it's simple to create a method to get the current Fragment by using the getCurrentItem() method of the ViewPager to get the current position.

    private MyFragment getCurrentFragment(){
      int position = viewPager.getCurrentItem(); //get current position

      List<MyFragment> fragments = getActiveFragments();
      for(MyFragment one: fragments){
         if (one.getPosition() == position)
           return one;
      }
      return null;
    }

Let me know how that worked out.

Community
  • 1
  • 1
Plato
  • 2,338
  • 18
  • 21
  • Works perfectly, thanks! Loaded it up my device and I saw it in action in sync with the last line of Led Zeppelin's Stairway To Heaven (Live 1973). – Kevin Mark Jun 24 '13 at 01:04