Отправка данных из вложенных фрагментов в родительский фрагмент
У меня есть 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();
Вышеупомянутое относится к полям родительского фрагмента; и как они первоначально создаются.
Ответы
Ответ 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();
отлично работает для вызова функции фрагмента