it-swarm.com.ru

Показать диалог из фрагмента?

У меня есть некоторые фрагменты, которые должны показать обычный диалог. В этих диалоговых окнах пользователь может выбрать ответ да/нет, и тогда фрагмент должен вести себя соответственно.

Теперь класс Fragment не имеет метода onCreateDialog() для переопределения, поэтому я предполагаю, что мне нужно реализовать диалоги снаружи, в Activity, содержащем его. Это нормально, но тогда Activity должен как-то сообщить выбранный ответ фрагменту. Конечно, я мог бы использовать здесь шаблон обратного вызова, так что фрагмент регистрируется в Activity с классом слушателя, и Activity сообщит ответ через тот или иной тип.

Но это кажется довольно большим беспорядком для такой простой задачи, как отображение "простого" диалога "да-нет" во фрагменте. Кроме того, таким образом, мое Fragment будет менее автономным.

Есть ли какой-нибудь более чистый способ сделать это?

Edit:

Ответ на этот вопрос на самом деле не объясняет подробно, как следует использовать DialogFragments для отображения диалогов из фрагментов. Итак, AFAIK, путь должен быть:

  1. Показать фрагмент.
  2. При необходимости создайте экземпляр DialogFragment.
  3. Установите исходный фрагмент в качестве цели этого DialogFragment с помощью .setTargetFragment().
  4. Показать DialogFragment с помощью .show () из исходного фрагмента.
  5. Когда пользователь выбирает какую-либо опцию в этом DialogFragment, уведомляет исходный фрагмент об этом выборе (например, пользователь нажал "да"), вы можете получить ссылку на исходный фрагмент с помощью .getTarget ().
  6. Уволить ДиалогФрагмент.
114
Zsombor Erdődy-Nagy

Вы должны использовать DialogFragment вместо этого.

37
mgv

Я должен с осторожностью усомниться в ранее принятом ответе, что использование DialogFragment является лучшим вариантом. Предполагается, что (основной) целью DialogFragment является отображение фрагментов, которые являются самими диалогами, а не отображение фрагментов, которые имеют диалоговых окон для отображения.

Я считаю, что использование активности фрагмента для посредничества между диалогом и фрагментом является предпочтительным вариантом.

29
Mark D

Вот полный пример фрагмента "Да/Нет":

Класс:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(Android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(Android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}

Чтобы начать диалог:

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // Create and show the dialog.
        SomeDialog newFragment = new SomeDialog ();
        newFragment.show(ft, "dialog");

Вы также можете позволить классу реализовать onClickListener и использовать его вместо встроенных слушателей.

Обратный вызов к действию

Если вы хотите реализовать обратный вызов, вот как это делается в вашей деятельности:

YourActivity extends Activity implements OnFragmentClickListener

а также

@Override
public void onFragmentClick(int action, Object object) {
    switch(action) {
        case SOME_ACTION:
        //Do your action here
        break;
    }
}

Класс обратного вызова:

public interface OnFragmentClickListener {
    public void onFragmentClick(int action, Object object);
}

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

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentClickListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement listeners!");
    }
}

И обратный вызов выполняется так:

mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.
24
Warpzit

Для меня это было следующим

MyFragment:

public class MyFragment extends Fragment implements MyDialog.Callback
{
    ShowDialog activity_showDialog;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            activity_showDialog = (ShowDialog)activity;
        }
        catch(ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be     implemented by Activity.", e);
            throw e;
        }
    }

    @Override
    public void onClick(View view) 
    {
        ...
        MyDialog dialog = new MyDialog();
        dialog.setTargetFragment(this, 1); //request code
        activity_showDialog.showDialog(dialog);
        ...
    }

    @Override
    public void accept()
    {
        //accept
    }

    @Override
    public void decline()
    {
        //decline
    }

    @Override
    public void cancel()
    {
        //cancel
    }

}

MyDialog:

public class MyDialog extends DialogFragment implements View.OnClickListener
{
    private EditText mEditText;
    private Button acceptButton;
    private Button rejectButton;
    private Button cancelButton;

    public static interface Callback
    {
        public void accept();
        public void decline();
        public void cancel();
    }

    public MyDialog()
    {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.dialogfragment, container);
        acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn);
        rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn);
        cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn);
        acceptButton.setOnClickListener(this);
        rejectButton.setOnClickListener(this);
        cancelButton.setOnClickListener(this);
        getDialog().setTitle(R.string.dialog_title);
        return view;
    }

    @Override
    public void onClick(View v)
    {
        Callback callback = null;
        try
        {
            callback = (Callback) getTargetFragment();
        }
        catch (ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e);
            throw e;
        }

        if (callback != null)
        {
            if (v == acceptButton)
            {   
                callback.accept();
                this.dismiss();
            }
            else if (v == rejectButton)
            {
                callback.decline();
                this.dismiss();
            }
            else if (v == cancelButton)
            {
                callback.cancel();
                this.dismiss();
            }
        }
    }
}

Деятельность:

public class MyActivity extends ActionBarActivity implements ShowDialog
{
    ..

    @Override
    public void showDialog(DialogFragment dialogFragment)
    {
        FragmentManager fragmentManager = getSupportFragmentManager();
        dialogFragment.show(fragmentManager, "dialog");
    }
}

Макет DialogFragment:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:orientation="vertical" >

    <TextView
        Android:id="@+id/dialogfragment_textview"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="20dp"
        Android:layout_centerHorizontal="true"
        Android:layout_marginBottom="10dp"
        Android:text="@string/example"/>

    <Button
        Android:id="@+id/dialogfragment_acceptbtn"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="20dp"
        Android:layout_centerHorizontal="true"
        Android:layout_below="@+id/dialogfragment_textview"
        Android:text="@string/accept"
        />

    <Button
        Android:id="@+id/dialogfragment_rejectbtn"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="10dp"
        Android:layout_alignLeft="@+id/dialogfragment_acceptbtn"
        Android:layout_below="@+id/dialogfragment_acceptbtn"
        Android:text="@string/decline" />

     <Button
        Android:id="@+id/dialogfragment_cancelbtn"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="10dp"
        Android:layout_marginBottom="20dp"
        Android:layout_alignLeft="@+id/dialogfragment_rejectbtn"
        Android:layout_below="@+id/dialogfragment_rejectbtn"
        Android:text="@string/cancel" />

     <Button
        Android:id="@+id/dialogfragment_heightfixhiddenbtn"
        Android:layout_width="200dp"
        Android:layout_height="20dp"
        Android:layout_marginTop="10dp"
        Android:layout_marginBottom="20dp"
        Android:layout_alignLeft="@+id/dialogfragment_cancelbtn"
        Android:layout_below="@+id/dialogfragment_cancelbtn"
        Android:background="@Android:color/transparent"
        Android:enabled="false"
        Android:text=" " />
</RelativeLayout>

Как видно из названия dialogfragment_heightfixhiddenbtn, я просто не мог найти способ исправить то, что высота нижней кнопки была уменьшена вдвое, несмотря на то, что я сказал wrap_content, поэтому я добавил скрытую кнопку, чтобы "разрезать" ее пополам. Извините за взлом.

12
EpicPandaForce
 public void showAlert(){


     AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
     LayoutInflater inflater = getActivity().getLayoutInflater();
     View alertDialogView = inflater.inflate(R.layout.test_dialog, null);
     alertDialog.setView(alertDialogView);

     TextView textDialog = (TextView) alertDialogView.findViewById(R.id.text_testDialogMsg);
     textDialog.setText(questionMissing);

     alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
             dialog.cancel();
         }
     });
     alertDialog.show();

}

где .test_dialog имеет пользовательский формат xml

3
Alex Zaraos

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

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

http://www.helloandroid.com/tutorials/how-display-custom-dialog-your-Android-application

ЭТО ТО, ЧТО Я ПЫТАЛСЯ ДОСТИГНУТЬ КОДЕКСОМ:

У меня есть MainActivity, которая содержит фрагмент. Я хотел, чтобы в верхней части макета появилось диалоговое окно для запроса ввода данных пользователем, а затем соответствующей обработки. см. Скриншот

Вот как выглядит onCreateView моего фрагмента

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_home_activity, container, false);

    Button addTransactionBtn = rootView.findViewById(R.id.addTransactionBtn);

    addTransactionBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Dialog dialog = new Dialog(getActivity());
            dialog.setContentView(R.layout.dialog_trans);
            dialog.setTitle("Add an Expense");
            dialog.setCancelable(true);

            dialog.show();

        }
    });

Надеюсь это тебе поможет

Дайте мне знать, если есть путаница. :)

1
Junaid Aziz
    public static void OpenDialog (Activity activity, DialogFragment fragment){

    final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();

    fragment.show(fm, "tag");
}
0
Elmar Fazlagic