Вопрос: Как создать обратный вызов из DialogFragment в другой Fragment. В моем случае, Активность должна полностью не знать о DialogFragment.
Считай, у меня есть
public class MyFragment extends Fragment implements OnClickListener
Тогда в какой-то момент я мог сделать
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
Где выглядит MyDialogFragment
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Но нет никакой гарантии, что слушатель будет рядом, если DialogFragment приостановится и возобновит свой жизненный цикл. Единственными гарантиями во фрагменте являются те, которые передаются через Bundle через setArguments и getArguments.
Существует способ ссылаться на активность, если это должен быть слушатель:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Но я не хочу, чтобы Activity прослушивала события, мне нужен фрагмент. Действительно, это может быть любой объект Java, который реализует OnClickListener.
Рассмотрим конкретный пример фрагмента, который представляет AlertDialog через DialogFragment. Он имеет кнопки Да / Нет. Как я могу отправить эти нажатия кнопки назад на фрагмент, который его создал?
источник
OnClickListener listener = (OnClickListener) getParentFragment();
вместо этого DialogFragment, а ваш основной фрагмент реализует интерфейс, как вы делали изначально.Ответы:
Активная деятельность совершенно не знает о DialogFragment.
Фрагмент класса:
Класс DialogFragment:
источник
setTargetFragment
иgetTargetFragment
. ИспользованиеonActivityResult
немного неясно. Вероятно, было бы лучше объявить свой собственный конкретный метод в вызывающей стороне фрагмента и использовать его вместо повторного использования onActivityResult. Но в этом все семантика.Решение TargetFragment не кажется лучшим вариантом для фрагментов диалогов, поскольку оно может быть создано
IllegalStateException
после уничтожения и повторного создания приложения. В этом случаеFragmentManager
не удалось найти целевой фрагмент, и вы получите сообщениеIllegalStateException
с таким:Похоже, что
Fragment#setTargetFragment()
он предназначен не для связи между дочерним и родительским фрагментами, а скорее для связи между родственными фрагментами.Таким образом, альтернативный способ - создать подобные фрагменты диалога, используя
ChildFragmentManager
родительский фрагмент, а не действияFragmentManager
:И используя интерфейс, в
onCreate
методеDialogFragment
вы можете получить родительский фрагмент:Осталось только вызвать метод обратного вызова после этих шагов.
Дополнительную информацию о проблеме можно получить по ссылке: https://code.google.com/p/android/issues/detail?id=54520.
источник
Я следовал этим простым шагам, чтобы сделать это.
DialogFragmentCallbackInterface
с некоторым методом, какcallBackMethod(Object data)
. Который вы бы звонили для передачи данных.DialogFragmentCallbackInterface
интерфейс в вашем фрагменте, какMyFragment implements DialogFragmentCallbackInterface
Во время
DialogFragment
создания установите ваш вызывающий фрагмент вMyFragment
качестве целевого фрагмента, который создал,DialogFragment
используйтеmyDialogFragment.setTargetFragment(this, 0)
проверку setTargetFragment (фрагмент фрагмента, int requestCode)Получите целевой объект фрагмента в свой
DialogFragment
, вызвавgetTargetFragment()
и приведя его к.DialogFragmentCallbackInterface
Теперь вы можете использовать этот интерфейс для отправки данных к вашему фрагменту.Это все сделано! просто убедитесь, что вы реализовали этот интерфейс в своем фрагменте.
источник
onActivityResult(request code, resultcode, intent)
для возврата результата во фрагмент1. Из фрагмента 1setTargetFragment()
и из фрагмента 2 используйтеgetTargetFragment()
. При использовании родительского / дочернего фрагмента для фрагментации или действия для фрагментирования вы можете использовать прослушиватель или обратный вызов, поскольку нет опасности утечки родительского фрагмента в дочернем фрагменте.Может быть, немного поздно, но может помочь другим людям с тем же вопросом, что и я.
Вы можете использовать
setTargetFragment
наDialog
перед показом, и в диалоге вы можете позвонить ,getTargetFragment
чтобы получить ссылку.источник
В руководстве « Общение с другими фрагментами» говорится, что фрагменты должны взаимодействовать через связанные действия .
источник
Вы должны определить
interface
в своем фрагменте класс и реализовать этот интерфейс в родительской активности. Подробности изложены здесь http://developer.android.com/guide/components/fragments.html#EventCallbacks . Код будет выглядеть примерно так:Фрагмент:
Деятельность:
источник
FragmentA
и он предполагает, что активность - этоOnArticleSelectedListener
не Фрагмент, который его начал.MyFragment
вы можете перейти к использованию обычногоAlertDialog
Правильный способ установить слушателя на фрагмент, установив его, когда он присоединен . У меня была проблема, что onAttachFragment () никогда не вызывался. После некоторого расследования я понял, что я использовал getFragmentManager вместо getChildFragmentManager
Вот как я это делаю:
Прикрепите его в onAttachFragment:
источник
Согласно официальной документации:
Фрагмент # setTargetFragment
Фрагмент # getTargetFragment
Так что вы можете сделать это:
источник
Я столкнулся с аналогичной проблемой. Решение, которое я обнаружил, было:
Объявите интерфейс в вашем DialogFragment так же, как это объяснил Джеймс МакКракен выше.
Реализуйте интерфейс в своей деятельности (не фрагмент! Это не очень хорошая практика).
Из метода обратного вызова в вашей деятельности вызовите требуемую публичную функцию в вашем фрагменте, которая выполняет ту работу, которую вы хотите сделать.
Таким образом, это становится двухступенчатым процессом: DialogFragment -> Activity и затем Activity -> Fragment
источник
Я получаю результат Fragment DashboardLiveWall (вызывающий фрагмент) из Fragment LiveWallFilterFragment (получающий фрагмент) Как это ...
где
setResult вернуться к вызывающему фрагменту, как
onActivityResult
источник
Обновлено:
Я создал библиотеку, основанную на моем гист-коде, который генерирует их для вас с помощью
@CallbackFragment
и@Callback
.https://github.com/zeroarst/callbackfragment .
И пример дает вам пример, который отправляет обратный вызов от фрагмента к другому фрагменту.
Старый ответ:
Я сделал
BaseCallbackFragment
и аннотацию@FragmentCallback
. В настоящее время он расширяетсяFragment
, вы можете изменить егоDialogFragment
и работать. Он проверяет реализации в следующем порядке: getTargetFragment ()> getParentFragment ()> context (activity).Затем вам просто нужно расширить его и объявить ваши интерфейсы в вашем фрагменте и дать ему аннотацию, а базовый фрагмент сделает все остальное. В аннотации также есть параметр,
mandatory
позволяющий вам определить, хотите ли вы заставить фрагмент реализовать обратный вызов.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
источник
Парни Kotlin здесь мы идем!
Итак, проблема у нас в том, что мы создали действие,
MainActivity
на этом действии мы создали фрагмент,FragmentA
и теперь мы хотим создать фрагмент диалога поверхFragmentA
вызова егоFragmentB
. Как мы можем получить результатыFragmentB
обратноFragmentA
без прохожденияMainActivity
?Примечание:
FragmentA
это дочерний фрагментMainActivity
. Для управления созданными фрагментамиFragmentA
мы будем использоватьchildFragmentManager
это!FragmentA
является родительским фрагментомFragmentB
, для доступаFragmentA
изнутриFragmentB
мы будем использоватьparenFragment
.Сказав это, внутри
FragmentA
,Вот фрагмент диалога
FragmentB
.Вот интерфейс, связывающий их.
Вот и все.
источник
Я решил это элегантно с помощью RxAndroid. Получите наблюдателя в конструкторе DialogFragment и запишите значение наблюдаемого и нажмите значение при вызове обратного вызова. Затем в своем фрагменте создайте внутренний класс Observer, создайте экземпляр и передайте его в конструктор DialogFragment. Я использовал WeakReference в обозревателе, чтобы избежать утечек памяти. Вот код:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Вы можете увидеть исходный код здесь: https://github.com/andresuarezz26/carpoolingapp
источник