Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getParentFragment API 16

We all know getParentFragment of Fragment is introduced in API 17.

So what if we want to get parent fragment in API 16 and below (Considering that I use native Fragment with support FragmentStatePagerAdapter and have no problem with nested fragments)

Is there any better way than mine?

In parent:

public class ParentFragment extends Fragment {

public static ParentFragment StaticThis;
...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

StaticThis = this;

...
}

In child:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
         parentFragment = (ParentFragment) getParentFragment();
else
         parentFragment = ParentFragment.StaticThis;
like image 636
Mohsen Afshin Avatar asked Dec 04 '13 13:12

Mohsen Afshin


2 Answers

Based on your comment if you want to talk back from the "items" in your ViewPager (I'm guessing this is a Fragment) to the container of the ViewPager which is a FragmentActivity you can use an interface.

(1) Either declar the interface in the Fragment itself or as a separate file (2) "Initialize" the inteface in your fragment's onAttach method. For example

 private SomeInterface blah;

 @Override
 public void onAttach(Activity activity){
    blah = (SomeInterface) activity;
 }

(3) Implement the interface in your FragmentActivity.

You can then callback to the FragmentActivity from your Fragment. From there you can call any method you want within the FragmentActivity or, if you get a reference to any of the other fragments that are loaded into your ViewPager, call any public method within that Fragment. This allows you to communicate between fragments and their container without a memory leak.

like image 87
Rarw Avatar answered Oct 18 '22 21:10

Rarw


To get the parent fragment in older (and newer) versions, I found a way around:

1) Set the tag of the ParentFragment in your activity (via .add() or .replace()). Check the link below for more info, or step 2 for a similar example in the ParentFragment : http://developer.android.com/reference/android/app/FragmentTransaction.html#add(android.app.Fragment, java.lang.String)

2) In the ParentFragment, collect the tag (using 'this'), and add it to the newInstance() of your ChildFragment:

  FragmentManager fragmentManager = getFragmentManager();
  FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

  // Get the fragment, if you want to re-use it
  ChildFragment fragment = (ChildFragment) fragmentManager.findFragmentByTag();

  // Create a new fragment if it doesn't already exist.
  if (fragment == null)
  {
     // Collect the tag of your ParentFragment and add it to the newInstance() of the ChildFragment
     String parentTag = this.getTag();
     fragment = ChildFragment.newInstance(parentTag);
  }
  // Put the fragment in the .replace() or .add() of the transaction.
  // You might use a childTag as well, but it's not necessary for solving your problem
  fragmentTransaction.replace(R.id.my_fragment_view, fragment, childTag);
  fragmentTransaction.commit();

3) Make sure to save the tag in the arguments of the ChildFragment. Collect the tag from the arguments in onAttach(), and collect the ParentFragment through the 'activity' parameter from onAttach():

private static final String PARENT_TAG = "parent_tag";
ParentFragment parentFragment;

public static ChildFragment newInstance(String parentTag)
{
   ChildFragment fragment = new ChildFragment();
   Bundle args = new Bundle();
   args.putString(PARENT_TAG, parentTag);
   fragment.setArguments(args);
   return fragment;
}

@Override
public void onAttach(Activity activity)
{
   super.onAttach(activity);

   // Collect the tag from the arguments
   String tag = getArguments().getString(PARENT_TAG);

   // Use the tag to get the parentFragment from the activity, which is (conveniently) available in onAttach()
   parentFragment = (ParentFragment) activity.getFragmentManager().findFragmentByTag(tag);
}

4) Now you've got your ParentFragment inside your ChildFragment and you can use it whenever you need it, so where you used this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
{
     parentFragment = (ParentFragment) getParentFragment();
}
else
{
     parentFragment = ParentFragment.StaticThis;
}

you can now:

parentFragment.justDoSomethingCoolWithIt(); // and prevent memory leaks through StaticThis ;-)
like image 23
P Kuijpers Avatar answered Oct 18 '22 21:10

P Kuijpers