Enviar datos de fragmentos nesteds al fragmento principal

Tengo un Fragment FR1 que contiene varios Fragments Nested ; FRa , FRb , FRc . Estos Fragments Nested se cambian presionando los Buttons en el diseño de FR1 . Cada uno de los Fragments Nested tiene varios campos de entrada dentro de ellos; que incluyen cosas como EditTexts , NumberPickers y Spinners . Cuando mi usuario realiza y rellena todos los valores para los Fragments Nested , FR1 (el fragmento principal) tiene un botón de envío.

¿Cómo puedo, entonces, recuperar mis valores de mis Fragments Nested y ponerlos en FR1 ?

  1. Todas las Views son declaradas y manejadas programáticamente dentro de cada Fragment Nested .
  2. El Fragment principal, FR1 maneja la transacción de los Fragments Nested .

Espero que esta pregunta sea lo suficientemente clara y no estoy seguro si el código es necesario para publicar, pero si alguien siente lo contrario, puedo hacerlo.

EDIT 1:

Aquí es cómo agrego mis Fragments Nested :

 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(); } }); 

donde mi método constructNewProfile() necesita los valores de mis Fragments Nested .

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

Lo anterior se refiere a los campos del fragmento principal; y cómo se crean inicialmente las instancias.

La mejor forma es usar una interfaz:

  1. Declarar una interfaz en el fragmento de nido

     // Container Activity or Fragment must implement this interface public interface OnPlayerSelectionSetListener { public void onPlayerSelectionSet(List players_ist); } 
  2. Adjunte la interfaz al fragmento principal

     // 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()); // ... } 
  3. Llamar al oyente al hacer clic en el botón.

     // 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; } } 
  4. Haga que su fragmento padre implemente la interfaz.

      public class Fragment_Parent extends Fragment implements Nested_Fragment.OnPlayerSelectionSetListener { // ... @Override public void onPlayerSelectionSet(final List 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. } } } 

Agregue Tag cuando fragmente la transacción para que luego pueda buscarla y llamar a su método. FragmentoTransacción

Esta es la forma correcta de manejar la comunicación entre el fragmento y el fragmento del nido, es casi lo mismo para la actividad y el fragmento. http://developer.android.com/guide/components/fragments.html#EventCallbacks

En realidad, hay otra forma oficial, está utilizando el resultado de la actividad, pero este es lo suficientemente bueno y común.

En lugar de usar la interfaz, puede llamar al fragmento hijo a continuación:

 ( (YourFragmentName) getParentFragment() ).yourMethodName(); 

Puede usar getChildFragmentManager() y encontrar fragmentos nesteds, obtenerlos y ejecutar algunos métodos para recuperar valores de entrada

Compruebe, por instanceOf antes de obtener el fragmento principal, que es mejor:

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

La mejor forma de pasar datos entre fragmentos es utilizando Interface. Esto es lo que debe hacer: en su fragmento nested:

 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); } 

En tu fragmento principal:

 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(); } } } 

Puede usar compartir datos entre fragmentos.

 public class SharedViewModel extends ViewModel { private final MutableLiveData selected = new MutableLiveData(); public void select(Item item) { selected.setValue(item); } public LiveData getSelected() { return selected; } } public class MasterFragment extends Fragment { private SharedViewModel model; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class); itemSelector.setOnClickListener(item -> { model.select(item); }); } } public class DetailFragment extends Fragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class); model.getSelected().observe(this, item -> { // Update the UI. }); } } 

Más información ViewModel Architecture