J'ai un Fragment
FR1
Qui contient plusieurs Nested
Fragments
; FRa
, FRb
, FRc
. Ces Nested
Fragments
sont modifiés en appuyant sur Buttons
sur la mise en page de FR1
. Chacun des Nested
Fragments
contient plusieurs champs de saisie; qui incluent des choses comme EditTexts
, NumberPickers
et Spinners
. Lorsque mon utilisateur parcourt et remplit toutes les valeurs de Nested
Fragments
, FR1
(Le fragment parent) a un bouton d'envoi.
Comment puis-je alors récupérer mes valeurs dans mon Nested
Fragments
et les importer dans FR1
.
Views
sont déclarés et gérés par programme dans chaque Nested
Fragment
.Fragment
, FR1
Gère la transaction du Nested
Fragments
.J'espère que cette question est suffisamment claire et je ne sais pas si le code est nécessaire à publier, mais si quelqu'un pense le contraire, je peux le faire.
MODIFIER 1:
Voici comment ajouter mon 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();
}
});
où ma méthode constructNewProfile()
a besoin des valeurs de mon 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();
Ce qui précède fait référence aux champs du fragment parent; et comment ils sont initialement instanciés.
La meilleure façon est d'utiliser une interface:
Déclarez une interface dans le fragment de nid
// Container Activity or Fragment must implement this interface
public interface OnPlayerSelectionSetListener
{
public void onPlayerSelectionSet(List<Player> players_ist);
}
Attachez l'interface au fragment parent
// 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());
// ...
}
Appelez l'auditeur en cliquant sur le bouton.
// 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;
}
}
Demandez à votre fragment parent d'implémenter l'interface.
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.
}
}
}
Ajoutez une balise lorsque vous effectuez une transaction fragmentée afin de pouvoir la rechercher par la suite pour appeler sa méthode. FragmentTransaction
C'est la bonne façon de gérer la communication entre le fragment et le fragment d'imbrication, c'est presque la même chose pour l'activité et le fragment. http://developer.Android.com/guide/components/fragments.html#EventCallbacks
Il existe en fait une autre méthode officielle, qui utilise le résultat de l'activité, mais celle-ci est assez bonne et courante.
Au lieu d'utiliser l'interface, vous pouvez appeler le fragment enfant via ci-dessous:
( (YourFragmentName) getParentFragment() ).yourMethodName();
Vous pouvez utiliser getChildFragmentManager()
et trouver des fragments imbriqués, les obtenir et exécuter certaines méthodes pour récupérer les valeurs d'entrée
La meilleure façon de transmettre des données entre fragments est d'utiliser Interface. Voici ce que vous devez faire: Dans votre fragment imbriqué:
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);
}
Dans votre fragment parent:
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();
}
}
}
Vérifiez instanceOf
avant d'obtenir le fragment parent, ce qui est mieux:
if (getParentFragment() instanceof ParentFragmentName) {
getParentFragment().Your_parent_fragment_method();
}
Vous pouvez utiliser le partage de données entre fragments.
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> 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.
});
}
}
Plus d'informations ViewModel Architecture