Wysyłanie danych z zagnieżdżonych fragmentów do fragmentu nadrzędnego
Mam Fragment
FR1
który zawiera kilka Nested
Fragments
; FRa
, FRb
, FRc
. Te Nested
Fragments
są zmieniane przez naciśnięcie Buttons
na układzie FR1
. Każdy z Nested
Fragments
mają w sobie kilka pól wejściowych, które zawierają takie rzeczy jakEditTexts
, NumberPickers
, i Spinners
. Kiedy mój użytkownik przechodzi i wypełnia wszystkie wartości dla Nested
Fragments
, FR1
(fragment nadrzędny) posiada przycisk submit.
Jak mogę odzyskać moje wartości z mojego Nested
Fragments
i doprowadzić je do FR1
.
- wszystkie
Views
są zadeklarowane i programowo obsługiwane w każdymNested
Fragment
. - rodzic
Fragment
,FR1
obsługuje transakcję zNested
Fragments
.
Mam nadzieję, że to pytanie jest wystarczająco jasne i nie jestem pewien, czy kod jest potrzebny do napisania, ale jeśli ktoś uważa inaczej, mogę to zrobić.
Edytuj 1:
Oto jak dodaję moje 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();
}
});
Gdzie moja metoda constructNewProfile()
potrzebuje wartości z mojej 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();
Powyższe odnosi się do pól fragmentu nadrzędnego; oraz do tego, jak są one początkowo tworzone.
6 answers
Najlepszym sposobem jest użycie interfejsu:
-
Zadeklaruj interfejs w fragmencie gniazda
// Container Activity or Fragment must implement this interface public interface OnPlayerSelectionSetListener { public void onPlayerSelectionSet(List<Player> players_ist); }
-
Dołączanie interfejsu do fragmentu nadrzędnego
// 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()); // ... }
-
Wywołanie słuchacza po kliknięciu przycisku.
// 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; } }
-
Niech twój fragment rodzica zaimplementuje interfejs.
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. } } }
Dodaj znacznik, gdy wykonujesz transakcję fragmentaryczną, abyś mógł go później wyszukać, aby wywołać jego metodę. FragmentTransaction
To jest właściwy sposób obsługi komunikacji między fragmentem a fragmentem gniazda, jest prawie taki sam dla aktywności i fragmentu. http://developer.android.com/guide/components/fragments.html#EventCallbacks
W rzeczywistości jest inny oficjalny sposób, to użycie wyniku aktywności, ale ten jest wystarczająco dobry i powszechny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 02:02:19
Zamiast używać interfejsu, możesz wywołać fragment potomny za pomocą poniższego kodu:
( (YourFragmentName) getParentFragment() ).yourMethodName();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 05:06:01
Możesz użyć getChildFragmentManager()
i znaleźć zagnieżdżone fragmenty, pobrać je i uruchomić kilka metod, aby pobrać wartości wejściowe
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-17 20:39:56
Sprawdź instanceOf
Przed pobraniem fragmentu rodzica, który jest lepszy:
if (getParentFragment() instanceof ParentFragmentName) {
getParentFragment().Your_parent_fragment_method();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 16:34:35
Najlepszym sposobem przekazywania danych pomiędzy fragmentami jest użycie interfejsu. Oto, co musisz zrobić: W zagnieżdżonym fragmencie:
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);
}
W fragmencie rodzica:
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();
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-31 22:00:27
Możesz użyć współdzielenia danych między fragmentami.
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.
});
}
}
Więcej Informacji ViewModel Architecture
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-10 06:44:16