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



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



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



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



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

825   9  

9 ответов:

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

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

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

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

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

затем добавьте ссылку на этот слушатель:

private EditNameDialogListener listener;

это будет использоваться для" активации " метода(ов) прослушивателя, а также для проверки, реализует ли родительская активность/фрагмент этот интерфейс (см. ниже).

на Activity/FragmentActivity/Fragment что "под названием"DialogFragment просто реализовать этот интерфейс.

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

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

здесь mEditText.getText().toString() это то, что будет передано обратно в вызов Activity.

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

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

@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.

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

@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.
         }
     }
}

The requestCode это в основном ваша метка int для DialogFragment, которую вы назвали, я покажу, как это работает через секунду. В resultCode-код, который вы отправить обратно из DialogFragment говорю текущей активности в ожидании, фрагмент, или FragmentActivity, что получилось.

следующий фрагмент кода для входа-это вызов 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 обратно в вашу вызывающую активность, фрагмент или FragmentActivity.

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

изменить 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);  

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

public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator

а то @Override в функция в деятельности

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

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

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

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

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

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

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

 @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 до Activity общение! Я считаю, что это намного проще и чище, чем другие предложения. По сути, вы регистрируетесь для вашего Activity чтобы слушать радиопередачи, и вы отправляете местные трансляции с вашего DialogFragment экземпляров. Простой. Пошаговое руководство по настройке всего этого см. В разделе здесь.

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

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

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

 public void onUserSelectValue(String selectedValue) {

        // TODO add your implementation.
      Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show();
    }

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

другой подход, чтобы позволить фрагмент общаться до его активность:

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

public OnFragmentInteractionListener mCallback;

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

2) приведите действие к переменной mCallback в фрагменте

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

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

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

просто чтобы иметь его в качестве одного из вариантов (так как никто еще не упоминал об этом) - вы можете использовать шину событий, такую как Otto. Итак, в диалоговом окне вы делаете:

bus.post(new AnswerAvailableEvent(42));

и ваш абонент (активность или фрагмент) подписаться на него:

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

Comments

    Ничего не найдено.