Отправка данных из вложенных фрагментов в родительский фрагмент
у меня есть Fragment
FR1
, который содержит несколько Nested
Fragments
; FRa
, FRb
, FRc
. Эти Nested
Fragments
изменяются нажатием кнопки Buttons
on FR1
's макет. Каждый из Nested
Fragments
имеют несколько полей ввода внутри них; которые включают такие вещи, как EditTexts
, NumberPickers
и Spinners
. Когда мой пользователь проходит и заполняет все значения Nested
Fragments
, FR1
(Родительский фрагмент) имеет кнопку отправки.
как я могу тогда, извлеките мои значения из my 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();
}
});
где мой constructNewProfile()
метод нуждается в значениях из my 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();
вышесказанное относится к полям родительского фрагмента; и как они изначально создаются.
6 ответов
лучший способ - использовать интерфейс:
-
объявить интерфейс во фрагменте гнезда
// 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
на самом деле есть еще один официальный способ, он использует результат деятельности, но этот достаточно хорош и распространен.
вместо использования интерфейса вы можете вызвать дочерний фрагмент ниже:
( (YourFragmentName) getParentFragment() ).yourMethodName();
можно использовать getChildFragmentManager()
и найти вложенные фрагменты, получить их и запустить некоторые методы для получения входных значений
проверить instanceOf
перед получением родительского фрагмента, который лучше:
if (getParentFragment() instanceof ParentFragmentName) {
getParentFragment().Your_parent_fragment_method();
}
лучший способ передачи данных между фрагментами - использовать интерфейс. Вот что тебе нужно сделать.: В вас вложен фрагмент:
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();
}
}
}
вы можете использовать обмен данными между фрагментами.
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.
});
}
}
Подробнее Архитектура ViewModel