Подтвердить что ты не робот

Отправка данных из вложенных фрагментов в родительский фрагмент

У меня есть Fragment FR1, который содержит несколько Nested Fragments; FRa, FRb, FRc. Эти Nested Fragments изменяются, нажимая Buttons на макете FR1. Каждый из Nested Fragments имеет в себе несколько полей ввода; которые включают такие вещи, как EditTexts, NumberPickers и Spinners. Когда мой пользователь проходит и заполняет все значения для Nested Fragments, FR1 (родительский фрагмент) имеет кнопку отправки.

Как я могу получить мои значения из моего Nested Fragments и привести их в FR1.

  • Все Views объявляются и программно обрабатываются в каждом Nested Fragment.
  • Родительский Fragment, FR1 обрабатывает транзакцию Nested Fragments.

Надеюсь, этот вопрос достаточно ясен, и я не уверен, нужен ли код для публикации, но если кто-то чувствует иначе, я могу это сделать.

РЕДАКТИРОВАТЬ 1:

Вот как я добавляю свой Nested Fragments:

tempRangeButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            getChildFragmentManager().beginTransaction()
                    .add(R.id.settings_fragment_tertiary_nest, tempFrag)
                    .commit();

        }
    });

    scheduleButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            getChildFragmentManager().beginTransaction()
                    .add(R.id.settings_fragment_tertiary_nest, scheduleFrag)
                    .commit();
        }
    });

    alertsButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            getChildFragmentManager().beginTransaction()
                    .add(R.id.settings_fragment_tertiary_nest, alertsFrag)
                    .commit();

        }
    });

    submitProfile.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            constructNewProfile();
        }
    });

где my constructNewProfile() метод нуждается в значениях из моего Nested Fragments.

public Fragment tempFrag = fragment_profile_settings_temperature
        .newInstance();
public Fragment scheduleFrag= fragment_profile_settings_schedules
            .newInstance();
public Fragment alertsFrag = fragment_profile_settings_alerts
        .newInstance();

Вышеупомянутое относится к полям родительского фрагмента; и как они первоначально создаются.

4b9b3361

Ответ 1

Лучший способ - использовать интерфейс:

  • Объявить интерфейс в фрагменте гнезда

    // Container Activity or Fragment must implement this interface
    public interface OnPlayerSelectionSetListener
    {
        public void onPlayerSelectionSet(List<Player> players_ist);
    }
    
  • Прикрепите интерфейс к родительскому фрагменту

    // In the child fragment.
    public void onAttachToParentFragment(Fragment fragment)
    {
        try
        {
            mOnPlayerSelectionSetListener = (OnPlayerSelectionSetListener)fragment;
    
        }
        catch (ClassCastException e)
        {
              throw new ClassCastException(
                  fragment.toString() + " must implement OnPlayerSelectionSetListener");
        }
    }
    
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.i(TAG, "onCreate");
        super.onCreate(savedInstanceState);
    
        onAttachToParentFragment(getParentFragment());
    
        // ...
    }
    
  • Вызовите слушателя нажатием кнопки.

    // In the child fragment.
    @Override
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.tv_submit:
                if (mOnPlayerSelectionSetListener != null)
                {                
                     mOnPlayerSelectionSetListener.onPlayerSelectionSet(selectedPlayers);
                }
                break;
            }
        }
    
  • Попросите родительский фрагмент реализовать интерфейс.

     public class Fragment_Parent extends Fragment implements Nested_Fragment.OnPlayerSelectionSetListener
     {
          // ...
          @Override
          public void onPlayerSelectionSet(final List<Player> players_list)
          {
               FragmentManager fragmentManager = getChildFragmentManager();
               SomeOtherNestFrag someOtherNestFrag = (SomeOtherNestFrag)fragmentManager.findFragmentByTag("Some fragment tag");
               //Tag of your fragment which you should use when you add
    
               if(someOtherNestFrag != null)
               {
                    // your some other frag need to provide some data back based on views.
                    SomeData somedata = someOtherNestFrag.getSomeData();
                    // it can be a string, or int, or some custom java object.
               }
          }
     }
    

Добавить тег, когда вы выполняете транзакцию фрагмента, чтобы впоследствии просмотреть его, чтобы вызвать его метод. FragmentTransaction

Это правильный способ обработки связи между фрагментом и фрагментом гнезда, он почти одинаковый для активности и фрагмента. http://developer.android.com/guide/components/fragments.html#EventCallbacks

На самом деле существует другой официальный способ: он использует результат деятельности, но этот уровень достаточно хорош и распространен.

Ответ 2

Вместо использования интерфейса вы можете вызвать дочерний фрагмент ниже:

( (YourFragmentName) getparentFragment() ).yourMethodName();

Ответ 3

Вы можете использовать getChildFragmentManager() и найти вложенные фрагменты, получить их и запустить некоторые методы для получения входных значений

Ответ 4

Лучший способ передачи данных между фрагментами - использовать интерфейс. Вот что вам нужно сделать: У вас вложенный фрагмент:

public interface OnDataPass {
    public void OnDataPass(int i);
}

OnDataPass dataPasser;

@Override
public void onAttach(Activity a) {
    super.onAttach(a);
    dataPasser = (OnDataPass) a;
}

public void passData(int i) {
    dataPasser.OnDataPass(i);
}

В вашем родительском фрагменте:

public class Fragment_Parent extends Fragment implements OnDataPass {
...

    @Override
    public void OnDataPass(int i) {
        this.input = i;
    }

    btnOk.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Fragment fragment = getSupportFragmentManager().findFragmentByTag("0");
            ((Fragment_Fr1) fragment).passData();
        }
    }

}

Ответ 5

Проверьте instanceOf перед тем, как лучше получить родительский фрагмент:

if (getParentFragment() instanceof ParentFragmentName) {
  getParentFragment().Your_parent_fragment_method();
}

Ответ 6

в моем случае (new Fragment()).hello(); отлично работает для вызова функции фрагмента