API getParentFragment 16

Мы все знаем, что getParentFragment of Fragment вводится в API 17.

Итак, что, если мы хотим получить родительский фрагмент в API 16 и ниже (учитывая, что я использую native Fragment с поддержкой FragmentStatePagerAdapter и не имею проблем с вложенными фрагментами)

Есть ли лучший способ, чем мой?

В родительском:

public class ParentFragment extends Fragment {

public static ParentFragment StaticThis;
...

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

StaticThis = this;

...
}

У ребенка:

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

Ответ 1

На основе вашего комментария, если вы хотите поговорить с "элементами" вашего ViewPager (я предполагаю, что это Fragment) в контейнере ViewPager, который является FragmentActivity, вы может использовать интерфейс.

(1) Либо объявить интерфейс в самом Fragment, либо в виде отдельного файла (2) "Инициализировать" inteface в вашем методе onAttach. Например

 private SomeInterface blah;

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

(3) Внедрите интерфейс в FragmentActivity.

Затем вы можете вернуться к FragmentActivity из Fragment. Оттуда вы можете вызвать любой метод, который вы хотите, в FragmentActivity или, если вы получите ссылку на любой из других фрагментов, загруженных в ваш ViewPager, вызовите любой общедоступный метод в пределах этого Fragment. Это позволяет вам общаться между фрагментами и их контейнером без утечки памяти.

Ответ 2

Чтобы получить родительский фрагмент в более старых (и более новых) версиях, я нашел способ:

1) Установите тэг ParentFragment в свою активность (через .add() или .replace()). Для получения дополнительной информации см. Приведенную ниже ссылку или шаг 2 для аналогичного примера в ParentFragment: http://developer.android.com/reference/android/app/FragmentTransaction.html # add (android.app.Fragment, java.lang.String)

2) В ParentFragment соберите тег (используя 'this') и добавьте его в newInstance() вашего 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 not necessary for solving your problem
  fragmentTransaction.replace(R.id.my_fragment_view, fragment, childTag);
  fragmentTransaction.commit();

3) Обязательно сохраните тег в аргументах ChildFragment. Соберите тег из аргументов в onAttach() и соберите ParentFragment через параметр activity из 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) Теперь у вас есть ParentFragment внутри вашего ChildFragment, и вы можете использовать его всякий раз, когда вам это нужно, поэтому, когда вы использовали это:

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

Теперь вы можете:

parentFragment.justDoSomethingCoolWithIt(); // and prevent memory leaks through StaticThis ;-)