Получать результат от DialogFragment

Я использую DialogFragments для нескольких вещей: выбор элемента из списка, ввод текста.

Каков наилучший способ вернуть значение (т. Е. Строку или элемент из списка) обратно в вызывающую активность / fragment?

В настоящее время я делаю DismissListener и предоставляю DialogFragment ссылку на эту активность. Затем Dialog вызывает метод OnDimiss в OnDimiss и действие захватывает результат из объекта DialogFragment. Очень беспорядочно, и он не работает при изменении конфигурации (изменение ориентации), поскольку DialogFragment теряет ссылку на активность.

Спасибо за любую помощь.

    Используйте myDialogFragment.setTargetFragment(this, MY_REQUEST_CODE) из того места, где вы показываете диалог, а затем, когда ваше диалоговое окно завершено, вы можете вызвать getTargetFragment().onActivityResult(getTargetRequestCode(), ...) и реализовать onActivityResult() в содержащем fragmentе.

    Это похоже на злоупотребление onActivityResult() , тем более что это вообще не связано с действиями. Но я видел, как это рекомендовалось официальными людьми Google, и, возможно, даже в демо-версиях api. Я думаю, что это то, для чего был добавлен g/setTargetFragment() .

    Как вы можете видеть здесь, есть очень простой способ сделать это.

    В DialogFragment добавьте прослушиватель интерфейса, например:

     public interface EditNameDialogListener { void onFinishEditDialog(String inputText); } 

    Затем добавьте ссылку на этот прослушиватель:

     private EditNameDialogListener listener; 

    Это будет использоваться для «активации» метода (-ов) слушателя, а также для проверки того, реализует ли этот родительский Activity / Fragment этот интерфейс (см. Ниже).

    В Activity / FragmentActivity / Fragment который называется « DialogFragment просто реализует этот интерфейс.

    В вашем DialogFragment все, что вам нужно добавить в момент, когда вы хотите отклонить DialogFragment и вернуть результат, это:

     listener.onFinishEditDialog(mEditText.getText().toString()); this.dismiss(); 

    Где mEditText.getText().toString() – это то, что будет передано вызывающей Activity .

    Обратите внимание: если вы хотите вернуть что-то другое, просто измените аргументы, которые принимает слушатель.

    Наконец, вы должны проверить, действительно ли интерфейс реализован родительским действием / fragmentом:

     @Override public void onAttach(Context context) { super.onAttach(context); // Verify that the host activity implements the callback interface try { // Instantiate the EditNameDialogListener so we can send events to the host listener = (EditNameDialogListener) context; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(context.toString() + " must implement EditNameDialogListener"); } } 

    Этот метод очень гибкий и позволяет перезвонить с результатом, даже если ваш дон не хочет отменить диалог.

    Существует гораздо более простой способ получить результат от DialogFragment.

    Во-первых, в вашей деятельности, fragmentе или fragmentации вам нужно добавить следующую информацию:

     @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { // Stuff to do, dependent on requestCode and resultCode if(requestCode == 1) { // 1 is an arbitrary number, can be any int // This is the return result of your DialogFragment if(resultCode == 1) { // 1 is an arbitrary number, can be any int // Now do what you need to do after the dialog dismisses. } } } 

    Код requestCode – это в основном ваш ярлык int для вызываемого DialogFragment, я покажу, как это работает за секунду. Код результата – это код, который вы отправляете обратно из диалогового windows «Диалог», в котором говорится, что произошло текущее ожидание активности, fragmentа или FragmentActivity.

    Следующий fragment кода для входа – это вызов DialogFragment. Пример:

     DialogFragment dialogFrag = new MyDialogFragment(); // This is the requestCode that you are sending. dialogFrag.setTargetFragment(this, 1); // This is the tag, "dialog" being sent. dialogFrag.show(getFragmentManager(), "dialog"); 

    С этими тремя строками вы объявляете свой DialogFragment, устанавливая requestCode (который вызовет onActivityResult (…) после отклонения диалога, и вы увидите диалог. Это так просто.

    Теперь в вашем DialogFragment вам нужно просто добавить одну строку непосредственно перед dismiss() чтобы вы отправили resultCode обратно в onActivityResult ().

     getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, getActivity().getIntent()); dismiss(); 

    Вот и все. Обратите внимание, что resultCode определяется как int resultCode который я установил resultCode = 1; в этом случае.

    Вот и все, теперь вы можете отправить результат вашего DialogFragment обратно в свою вызывающую активность, fragment или fragmentацию.

    Кроме того, похоже, что эта информация была опубликована ранее, но не было достаточного примера, поэтому я подумал, что подробно расскажу.

    EDIT 06.24.2016 Приносим извинения за вводящий в заблуждение код выше. Но вы, конечно же, не можете получить результат обратно к деятельности, видящей в качестве строки:

     dialogFrag.setTargetFragment(this, 1); 

    устанавливает целевой Fragment а не Activity . Поэтому для этого вам необходимо использовать InterfaceCommunicator .

    В DialogFragment задается глобальная переменная

     public InterfaceCommunicator interfaceCommunicator; 

    Создайте публичную функцию для ее обработки

     public interface InterfaceCommunicator { void sendRequestCode(int code); } 

    Затем, когда вы будете готовы отправить код обратно в Activity когда DialogFragment будет запущен, вы просто добавите строку перед dismiss(); ваш DialogFragment :

     interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose. 

    В вашей деятельности теперь вам нужно сделать две вещи: первая – удалить одну строку кода, которая больше не применима:

     dialogFrag.setTargetFragment(this, 1); 

    Затем реализуйте интерфейс, и все готово. Вы можете сделать это, добавив следующую строку в предложение «Инициализация» в самом верху вашего classа:

     public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator 

    И затем @Override функции в активности,

     @Override public void sendRequestCode(int code) { // your code here } 

    Вы используете этот метод интерфейса так же, как и метод onActivityResult() . За исключением метода интерфейса для DialogFragments а другой для Fragments .

    Ну, может быть, слишком поздно ответить, но вот что я сделал, чтобы получить результаты от DialogFragment . очень похоже на ответ @ brandon. Здесь я DialogFragment из fragmentа, просто поместите этот код, где вы вызываете свой диалог.

     FragmentManager fragmentManager = getFragmentManager(); categoryDialog.setTargetFragment(this,1); categoryDialog.show(fragmentManager, "dialog"); 

    где categoryDialog – это мой DialogFragment который я хочу вызвать, и после этого в вашей реализации dialogfragment размещает этот код, где вы устанавливаете свои данные в намерениях. Значение resultCode равно 1, вы можете установить его или использовать System Defined.

      Intent intent = new Intent(); intent.putExtra("listdata", stringData); getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent); getDialog().dismiss(); 

    теперь пришло время вернуться к вызывающему fragmentу и реализовать этот метод. проверьте достоверность данных или результат, если хотите, с resultCode и resultCode .

      @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //do what ever you want here, and get the result from intent like below String myData = data.getStringExtra("listdata"); Toast.makeText(getActivity(),data.getStringExtra("listdata"),Toast.LENGTH_SHORT).show(); } 

    Я очень удивлен, увидев, что никто не предложил использовать местные трансляции для DialogFragment to Activity ! Я считаю, что это намного проще и чище, чем другие предложения. По существу, вы регистрируетесь для своей Activity чтобы прослушивать трансляции, и вы отправляете локальные трансляции из ваших экземпляров DialogFragment . Просто. Для пошагового руководства о том, как установить все это, см. Здесь .

    Один простой способ, который я нашел, это следующее: реализовать это ваш диалог,

      CallingActivity callingActivity = (CallingActivity) getActivity(); callingActivity.onUserSelectValue("insert selected value here"); dismiss(); 

    А затем в операции, которая называется fragmentом диалога, создайте соответствующую функцию как таковую:

      public void onUserSelectValue(String selectedValue) { // TODO add your implementation. Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show(); } 

    Тост должен показать, что он работает. Работал для меня.

    Разный подход, позволяющий fragmentу связываться с его деятельностью :

    1) Определить открытый интерфейс в fragmentе и создать для него переменную

     public OnFragmentInteractionListener mCallback; public interface OnFragmentInteractionListener { void onFragmentInteraction(int id); } 

    2) Передача активности переменной mCallback во fragmentе

     try { mCallback = (OnFragmentInteractionListener) getActivity(); } catch (Exception e) { Log.d(TAG, e.getMessage()); } 

    3) Внедрение слушателя в вашу деятельность

     public class MainActivity extends AppCompatActivity implements DFragment.OnFragmentInteractionListener { //your code here } 

    4) переопределить OnFragmentInteraction в активности

     @Override public void onFragmentInteraction(int id) { Log.d(TAG, "received from fragment: " + id); } 

    Дополнительная информация о нем: https://developer.android.com/training/basics/fragments/communicating.html

    В моем случае мне нужно было передать аргументы целевому fragmentу. Но у меня есть исключение «Фрагмент уже активен». Поэтому я объявил интерфейс в моем диалоговомfragmentе, который реализовал parentFragment. Когда parentFragment запустил DialogFragment, он установил себя как TargetFragment. Затем в DialogFragment я позвонил

      ((Interface)getTargetFragment()).onSomething(selectedListPosition); 

    Просто чтобы это было как один из вариантов (так как никто еще не упомянул об этом) – вы можете использовать автобус событий, например Отто. Итак, в диалоговом окне вы делаете:

     bus.post(new AnswerAvailableEvent(42)); 

    И пусть ваш абонент (активность или fragment) подписаться на него:

     @Subscribe public void answerAvailable(AnswerAvailableEvent event) { // TODO: React to the event somehow! } 
    Interesting Posts

    Почему у вас нет внешнего ключа в полиморфной ассоциации?

    Постоянно вставляйте строки из верхней части страницы в Excel

    Windows 7, клавиатура Lenovo

    Кнопка «Отправить форму» работает только после перезагрузки

    Вопрос о поведении C для неподписанного целого нижнего streamа

    Почему одно горячее кодирование улучшает производительность машинного обучения?

    LINQ: передача lambda-выражения в качестве параметра для выполнения и возврата методом

    java.security.cert.CertificateException: сертификаты не соответствуют ограничениям алгоритма

    Компилятор MATLAB против MATLAB Coder

    Вопросы об объекте Entity Framework Context Lifetime

    Могу ли я сериализовать вложенные свойства в мой class за одну операцию с помощью Json.net?

    Что такое состояния CLOSE_WAIT и TIME_WAIT?

    Пользовательские обои для Windows 7

    Какие выражения дают ссылочный тип, когда к ним применяется метод decltype?

    Как я могу размножать и делить, используя только смещение и добавление битов?

    Давайте будем гением компьютера.