Android 대화 상자 Fragment vs Dialog


244

구글은 우리가 사용하는 것이 좋습니다 DialogFragment간단한 대신 Dialog사용하여 Fragments API,하지만 고립 사용하는 것이 불합리 DialogFragment간단한 예 - 아니오 확인 메시지 상자를. 이 경우 가장 좋은 방법은 무엇입니까?


5
간단히 말해, 무엇보다 간단 Dialog하거나 AlertDialog.Builder::create()::show()화면을 회전 할 때 사라지는 대화 상자가 만들어집니다.
user1032613

답변:


83

예, 사용 DialogFragment및에서 onCreateDialog당신은 단순히 간단하게 만들 어쨌든에 AlertDialog를 사용하여 빌더 수 있습니다 AlertDialog예 / 아니오 확인 버튼을. 전혀 코드가 많지 않습니다.

당신의 조각에서 이벤트를 처리 안부를 수행하는 여러 가지 방법이있을 것입니다하지만 난 단순히 메시지를 정의로 HandlerFragment의에 전달할 DialogFragment생성자를 통해 다음 메시지가 다양한 클릭 이벤트에 approprirate 나의 조각의 핸들러에 다시 전달합니다. 다시 여러 가지 방법으로 수행하지만 다음은 저에게 효과적입니다.

대화 상자에서 메시지를 잡고 생성자에서 인스턴스화하십시오.

private Message okMessage;
...
okMessage = handler.obtainMessage(MY_MSG_WHAT, MY_MSG_OK);

onClickListener대화 상자에서를 구현 한 다음 적절하게 핸들러를 호출하십시오.

public void onClick(.....
    if (which == DialogInterface.BUTTON_POSITIVE) {
        final Message toSend = Message.obtain(okMessage);
        toSend.sendToTarget();
    }
 }

편집하다

그리고 Message소포 가능하므로 저장 onSaveInstanceState하고 복원 할 수 있습니다

outState.putParcelable("okMessage", okMessage);

그런 다음 onCreate

if (savedInstanceState != null) {
    okMessage = savedInstanceState.getParcelable("okMessage");
}

4
문제는 okMessage가 아닙니다. 문제는 okMessage target이며 번들에서로드하면 null이됩니다. Message의 대상이 null이고를 사용 sendToTarget하면 Message가 null이 아니기 때문에 대상이 NullPointerException을 얻게됩니다.
44 초

2
대화 상자 대신 DialogFragment를 사용하면 어떤 이점이 있습니까?
Raphael Petegrosso

80
DialogFragment를 사용하면 대화의 모든 수명주기가 처리된다는 이점이 있습니다. '대화창이 누출되었습니다 ...'라는 오류가 다시 발생하지 않습니다. DialogFragment로 이동하여 대화 상자를 잊어 버리십시오.
Snicolas

6
생성자를 통해 okMessage를 전달하는 대신 setArguments () 및 getArguments ()를 사용해야한다고 생각합니다.
pjv 2016 년

1
글쎄, 나는 사용자 빌더를 매우 쉽게 사용 하고이 android : configChanges = "locale | keyboardHidden | orientation | screenSize"로 활동 관리를 처리하고 응용 프로그램에서 아무런 문제도 보지 않습니다 ...
Renetik

67

YesNoDialog 및 OkDialog와 같은 일반 DialogFragment 하위 클래스를 만들고 앱에서 대화 상자를 많이 사용하는 경우 제목과 메시지를 전달할 수 있습니다.

public class YesNoDialog extends DialogFragment
{
    public static final String ARG_TITLE = "YesNoDialog.Title";
    public static final String ARG_MESSAGE = "YesNoDialog.Message";

    public YesNoDialog()
    {

    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Bundle args = getArguments();
        String title = args.getString(ARG_TITLE);
        String message = args.getString(ARG_MESSAGE);

        return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, null);
                }
            })
            .create();
    }
}

그런 다음 다음을 사용하여 호출하십시오.

    DialogFragment dialog = new YesNoDialog();
    Bundle args = new Bundle();
    args.putString(YesNoDialog.ARG_TITLE, title);
    args.putString(YesNoDialog.ARG_MESSAGE, message);
    dialog.setArguments(args);
    dialog.setTargetFragment(this, YES_NO_CALL);
    dialog.show(getFragmentManager(), "tag");

에서 결과를 처리하십시오 onActivityResult.


예, DialogFragment는 모든 수명주기 이벤트를 처리합니다.
ashishduh

1
나는 회전 된 대화 상자가 여전히 존재하고 오래된 존재하지 않는 조각에 assignent를 유지 한 후 있기 때문에하지 않는 생각 (dialog.setTargetFragment (이, YES_NO_CALL);) 그래서 회전 후 getTargetFragment () onActivityResult를 작동하지 않음.
Malachiasz

7
무엇 YES_NO_CALL, getFragmentManager()그리고 onActivityResult?
msysmilu

2
YES_NO_CALL요청 코드 인 사용자 지정 int입니다. getFragmentManager()활동에 대한 프래그먼트 관리자를 가져 onActivityResult()오며 프래그먼트 라이프 사이클 콜백 메소드입니다.
ashishduh

3
getFragmentManager ()를 getSupportFragmentManager ()로 교체하십시오.
Avinash Verma 2018 년

33

AlertDialog를 통해 DialogFragment를 사용하십시오.


  • API 레벨 13이 도입 된 이후 :

    Activity 의 showDialog 메소드는 사용되지 않습니다 . 대화 상자를 직접 관리해야하기 때문에 코드의 다른 곳에서 대화 상자를 호출하는 것은 바람직하지 않습니다 (예 : 방향 변경).

  • 차이 대화 상자

    그들은 너무 다른가요? DialogFragment 에 관한 Android 참조에서 :

    DialogFragment는 활동 창 위에 떠있는 대화 상자 창을 표시하는 조각입니다. 이 프래그먼트에는 프래그먼트의 상태에 따라 적절하게 표시되는 Dialog 오브젝트가 있습니다. (이를 기각, 숨기기를 표시 할 때 결정) 대화 상자의 제어 API를 통해 수행해야합니다 여기 가 아닌 대화에 직접 전화로.

  • 기타 노트

    • 조각은 화면 크기가 다른 장치의 다양성으로 인해 Android 프레임 워크에서 자연스럽게 진화 한 것입니다.
    • DialogFragments 및 Fragment는 지원 라이브러리에서 사용할 수 있으므로 현재 사용되는 모든 Android 버전에서 클래스를 사용할 수 있습니다.

28

을 사용하는 것이 좋습니다 DialogFragment.

물론 "예 / 아니오"대화 상자를 만드는 것은 간단한 작업이어야한다는 점을 고려하면 매우 복잡하지만 비슷한 대화 상자를 만드는 Dialog것도 놀라 울 정도로 복잡합니다.

(활동 수명주기는 복잡해집니다- Activity대화 상자의 수명주기를 관리 해야합니다.) - Activity.showDialog8 이하의 API 레벨을 사용 하는 경우 사용자 정의 메시지를 전달하는 방법은 없습니다.

좋은 점은 일반적으로 DialogFragment쉽게 자신의 추상화를 작성할 수 있다는 것입니다 .


경고 대화 상자 콜백을 처리하는 방법 (예, 아니오)?
Alexey Zakharov

가장 쉬운 방법은 String매개 변수 를 사용하는 호스팅 활동에서 메소드를 구현하는 것입니다 . 예를 들어, 사용자가 "예"를 클릭하면 대화 상자는 매개 변수 "agree"를 사용하여 활동의 메소드를 호출합니다. 이러한 매개 변수는 대화 상자를 표시 할 때 지정됩니다 (예 : AskDialog.ask ( "이 용어에 동의하십니까?", "agree", "disagree");
hrnt

5
그러나 활동이 아닌 조각 내부의 콜백이 필요합니다. setTargetFragment를 사용하여 인터페이스에 캐스트 할 수 있습니다. 그러나 그것은 지옥입니다.
Alexey Zakharov

또한 대상에 태그를 설정하고 사용하여 대상 조각을 가져올 수 FragmentManager'들 findFragmentByTag. 그러나 예, 약간의 코드가 필요합니다.
hrnt

@AlexeyZakharov 나는 이것이 약 5 년 늦었다는 것을 알고 있지만 당신은 통과하고 Fragment this 당신 Activity extends의 것을 가질 수 있습니다 Interface. 스레딩을 조심하면서 동시성을 확인하지 않으면 인터페이스 호출을 원하지 않을 때 인터페이스 호출이 발생할 수 있습니다. 이것이 메모리와 순환 종속성 스파게티로 무엇을하는지 잘 모르는 사람이 있습니까? 다른 옵션은 Message/ Handler이지만 여전히 동시성 문제가있을 수 있습니다.
tricknology

8

빌더 패턴이있는 일반 AlertDialogFragment

내 프로젝트 에서 문제가 있음을 알기 전에 AlertDialog.Builder이미 이미 많이 사용 했습니다. 그러나 내 앱의 어느 곳에서나 많은 코드를 변경하고 싶지 않았습니다. 또한 실제로 대화 상자 조각과 홀더 조각 사이에 통신하기 위해 수천 개의 콜백 메소드를 구현 해야하는 대신 OnClickListeners익명 클래스로 필요한 클래스 (즉 setPositiveButton(), setNegativeButton()등을 사용하는 경우)를 전달하는 팬입니다 . 내 의견은 매우 혼란스럽고 복잡한 코드로 이어집니다. 특히 하나의 조각에 여러 개의 다른 대화 상자가 있고 현재 표시되는 대화 상자 사이의 콜백 구현을 구별 해야하는 경우.

따라서 다른 접근 방식을 결합하여 다음 과 같이 정확하게AlertDialogFragment 사용할 수 있는 일반 도우미 클래스 를 만들었습니다 . AlertDialog


해결책

( 제발 참고 당신은 당신이 사용하지 않는 경우 코드의 일부를 변경해야 할 수도 있습니다, 그래서 내가, 내 코드에서 자바 8 람다 표현식을 사용하고 있음을 람다 표현식을 아직.)

/**
 * Helper class for dialog fragments to show a {@link AlertDialog}. It can be used almost exactly
 * like a {@link AlertDialog.Builder}
 * <p />
 * Creation Date: 22.03.16
 *
 * @author felix, http://flx-apps.com/
 */
public class AlertDialogFragment extends DialogFragment {
    protected FragmentActivity activity;
    protected Bundle args;
    protected String tag = AlertDialogFragment.class.getSimpleName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = getActivity();
        args = getArguments();
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = setDialogDefaults(new AlertDialog.Builder(getActivity())).create();

        if (args.containsKey("gravity")) {
            dialog.getWindow().getAttributes().gravity = args.getInt("gravity");
        }

        dialog.setOnShowListener(d -> {
            if (dialog != null && dialog.findViewById((android.R.id.message)) != null) {
                ((TextView) dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
            }
        });
        return dialog;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);

        if (args.containsKey("onDismissListener")) {
            Parcelable onDismissListener = args.getParcelable("onDismissListener");
            if (onDismissListener != null && onDismissListener instanceof ParcelableOnDismissListener) {
                ((ParcelableOnDismissListener) onDismissListener).onDismiss(this);
            }
        }
    }

    /**
     * Sets default dialog properties by arguments which were set using {@link #builder(FragmentActivity)}
     */
    protected AlertDialog.Builder setDialogDefaults(AlertDialog.Builder builder) {
        args = getArguments();
        activity = getActivity();

        if (args.containsKey("title")) {
            builder.setTitle(args.getCharSequence("title"));
        }

        if (args.containsKey("message")) {
            CharSequence message = args.getCharSequence("message");
            builder.setMessage(message);
        }

        if (args.containsKey("viewId")) {
            builder.setView(getActivity().getLayoutInflater().inflate(args.getInt("viewId"), null));
        }

        if (args.containsKey("positiveButtonText")) {
            builder.setPositiveButton(args.getCharSequence("positiveButtonText"), (dialog, which) -> {
                onButtonClicked("positiveButtonListener", which);
            });
        }

        if (args.containsKey("negativeButtonText")) {
            builder.setNegativeButton(args.getCharSequence("negativeButtonText"), (dialog, which) -> {
                onButtonClicked("negativeButtonListener", which);
            });
        }

        if (args.containsKey("neutralButtonText")) {
            builder.setNeutralButton(args.getCharSequence("neutralButtonText"), (dialog, which) -> {
                onButtonClicked("neutralButtonListener", which);
            });
        }

        if (args.containsKey("items")) {
            builder.setItems(args.getStringArray("items"), (dialog, which) -> {
                onButtonClicked("itemClickListener", which);
            });
        }

        // @formatter:off
        // FIXME this a pretty hacky workaround: we don't want to show the dialog if onClickListener of one of the dialog's button click listener were lost
        //       the problem is, that there is no (known) solution for parceling a OnClickListener in the long term (only for state changes like orientation change,
        //       but not if the Activity was completely lost)
        if (
                (args.getParcelable("positiveButtonListener") != null && !(args.getParcelable("positiveButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("negativeButtonListener") != null && !(args.getParcelable("negativeButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("neutralButtonListener") != null && !(args.getParcelable("neutralButtonListener") instanceof ParcelableOnClickListener)) ||
                (args.getParcelable("itemClickListener") != null && !(args.getParcelable("itemClickListener") instanceof ParcelableOnClickListener))
        ) {
            new DebugMessage("Forgot onClickListener. Needs to be dismissed.")
                    .logLevel(DebugMessage.LogLevel.VERBOSE)
                    .show();
            try {
                dismissAllowingStateLoss();
            } catch (NullPointerException | IllegalStateException ignored) {}
        }
        // @formatter:on

        return builder;
    }

    public interface OnDismissListener {
        void onDismiss(AlertDialogFragment dialogFragment);
    }

    public interface OnClickListener {
        void onClick(AlertDialogFragment dialogFragment, int which);
    }

    protected void onButtonClicked(String buttonKey, int which) {
        ParcelableOnClickListener parcelableOnClickListener = getArguments().getParcelable(buttonKey);
        if (parcelableOnClickListener != null) {
            parcelableOnClickListener.onClick(this, which);
        }
    }

    // region Convenience Builder Pattern class almost similar to AlertDialog.Builder
    // =============================================================================================

    public AlertDialogFragment builder(FragmentActivity activity) {
        this.activity = activity;
        this.args = new Bundle();
        return this;
    }

    public AlertDialogFragment addArguments(Bundle bundle) {
        args.putAll(bundle);
        return this;
    }

    public AlertDialogFragment setTitle(int titleStringId) {
        return setTitle(activity.getString(titleStringId));
    }

    public AlertDialogFragment setTitle(CharSequence title) {
        args.putCharSequence("title", title);
        return this;
    }

    public AlertDialogFragment setMessage(int messageStringId) {
        return setMessage(activity.getString(messageStringId));
    }

    public AlertDialogFragment setMessage(CharSequence message) {
        args.putCharSequence("message", message);
        return this;
    }

    public AlertDialogFragment setPositiveButton(int textStringId, OnClickListener onClickListener) {
        return setPositiveButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setPositiveButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("positiveButtonText", text);
        args.putParcelable("positiveButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setNegativeButton(int textStringId, AlertDialogFragment.OnClickListener onClickListener) {
        return setNegativeButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setNegativeButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("negativeButtonText", text);
        args.putParcelable("negativeButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setNeutralButton(int textStringId, AlertDialogFragment.OnClickListener onClickListener) {
        return setNeutralButton(activity.getString(textStringId), onClickListener);
    }

    public AlertDialogFragment setNeutralButton(CharSequence text, AlertDialogFragment.OnClickListener onClickListener) {
        args.putCharSequence("neutralButtonText", text);
        args.putParcelable("neutralButtonListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setOnDismissListener(OnDismissListener onDismissListener) {
        if (onDismissListener == null) {
            return this;
        }

        Parcelable p = new ParcelableOnDismissListener() {
            @Override
            public void onDismiss(AlertDialogFragment dialogFragment) {
                onDismissListener.onDismiss(dialogFragment);
            }
        };
        args.putParcelable("onDismissListener", p);
        return this;
    }

    public AlertDialogFragment setItems(String[] items, AlertDialogFragment.OnClickListener onClickListener) {
        args.putStringArray("items", items);
        args.putParcelable("itemClickListener", createParcelableOnClickListener(onClickListener));
        return this;
    }

    public AlertDialogFragment setView(int viewId) {
        args.putInt("viewId", viewId);
        return this;
    }

    public AlertDialogFragment setGravity(int gravity) {
        args.putInt("gravity", gravity);
        return this;
    }

    public AlertDialogFragment setTag(String tag) {
        this.tag = tag;
        return this;
    }

    public AlertDialogFragment create() {
        setArguments(args);
        return AlertDialogFragment.this;
    }

    public AlertDialogFragment show() {
        create();
        try {
            super.show(activity.getSupportFragmentManager(), tag);
        }
        catch (IllegalStateException e1) {

            /**
             * this whole part is used in order to attempt to show the dialog if an
             * {@link IllegalStateException} was thrown (it's kinda comparable to
             * {@link FragmentTransaction#commitAllowingStateLoss()} 
             * So you can remove all those dirty hacks if you are sure that you are always
             * properly showing dialogs in the right moments
             */

            new DebugMessage("got IllegalStateException attempting to show dialog. trying to hack around.")
                    .logLevel(DebugMessage.LogLevel.WARN)
                    .exception(e1)
                    .show();

            try {
                Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
                mShownByMe.setAccessible(true);
                mShownByMe.set(this, true);
                Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
                mDismissed.setAccessible(true);
                mDismissed.set(this, false);
            }
            catch (Exception e2) {
                new DebugMessage("error while showing dialog")
                        .exception(e2)
                        .logLevel(DebugMessage.LogLevel.ERROR)
                        .show();
            }
            FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
            transaction.add(this, tag);
            transaction.commitAllowingStateLoss(); // FIXME hacky and unpredictable workaround
        }
        return AlertDialogFragment.this;
    }

    @Override
    public int show(FragmentTransaction transaction, String tag) {
        throw new NoSuchMethodError("Please use AlertDialogFragment.show()!");
    }

    @Override
    public void show(FragmentManager manager, String tag) {
        throw new NoSuchMethodError("Please use AlertDialogFragment.show()!");
    }

    protected ParcelableOnClickListener createParcelableOnClickListener(AlertDialogFragment.OnClickListener onClickListener) {
        if (onClickListener == null) {
            return null;
        }

        return new ParcelableOnClickListener() {
            @Override
            public void onClick(AlertDialogFragment dialogFragment, int which) {
                onClickListener.onClick(dialogFragment, which);
            }
        };
    }

    /**
     * Parcelable OnClickListener (can be remembered on screen rotation)
     */
    public abstract static class ParcelableOnClickListener extends ResultReceiver implements AlertDialogFragment.OnClickListener {
        public static final Creator<ResultReceiver> CREATOR = ResultReceiver.CREATOR;

        ParcelableOnClickListener() {
            super(null);
        }

        @Override
        public abstract void onClick(AlertDialogFragment dialogFragment, int which);
    }

    /**
     * Parcelable OnDismissListener (can be remembered on screen rotation)
     */
    public abstract static class ParcelableOnDismissListener extends ResultReceiver implements AlertDialogFragment.OnDismissListener {
        public static final Creator<ResultReceiver> CREATOR = ResultReceiver.CREATOR;

        ParcelableOnDismissListener() {
            super(null);
        }

        @Override
        public abstract void onDismiss(AlertDialogFragment dialogFragment);
    }


    // =============================================================================================
    // endregion
}

용법

// showing a normal alert dialog with state loss on configuration changes (like device rotation)
new AlertDialog.Builder(getActivity())
        .setTitle("Are you sure? (1)")
        .setMessage("Do you really want to do this?")
        .setPositiveButton("Yes", (dialog, which) -> Toast.makeText(getContext(), "Yes clicked", Toast.LENGTH_SHORT).show())
        .setNegativeButton("Cancel", null)
        .show();

// showing a dialog fragment using the helper class with no state loss on configuration changes
new AlertDialogFragment.builder(getActivity())
        .setTitle("Are you sure? (2)")
        .setMessage("Do you really want to do this?")
        .setPositiveButton("Yes", (dialog, which) -> Toast.makeText(getContext(), "Yes clicked", Toast.LENGTH_SHORT).show())
        .setNegativeButton("Cancel", null)
        .show();

나는 여기에 내 솔루션을 공유 할뿐만 아니라 사람들에게 당신의 의견을 묻고 싶기 때문에 이것을 게시하고 있습니다.이 접근법은 합법적이거나 어느 정도 문제가 있습니까?


3
이것은 매우 흥미로운 아이디어이지만 API 디자인이 작동한다고 생각하지 않습니다. OnClickListener를 setPositiveButton ()에 전달하면 장치가 회전하고 번들 인수에서 프래그먼트가 다시 생성 될 때 OnClickListener가 Parcelable에서 올바르게 다시 생성되지 않습니다. 근본적인 문제는 회전 중에 리스너를 다시 만들 수 없지만 API 인터페이스 (인터페이스를 필요로하는)는 리스너를 요구한다는 것입니다. 나는 이것이 사실이 아니길 바란다.
Xargs

1
좋은 생각이지만 @Xargs가 말했듯이 작동하지 않습니다. 전달시 전달 된 리스너가 올바르게 다시 작성되지 않습니다.
Graham Borland

내 결과는 실제로 회전 및 응용 프로그램으로 다시 돌아갈 때 작동하지만 (예 : 홈 화면으로 이동 한 후) 활동이 완전히 파괴 된 후 복원되지 않은 경우 (OnClickListeners가 실제로 손실 됨)는 아닙니다. (Android 4.4.4 및 Android 5.1.1에서 테스트)
flxapps

나는이 정확한 구현을 테스트하지는 않았지만 테스트 한 것으로부터 조각 번들로 전달 된 소포 리스너가 재생성시 올바르게 호출됩니다. 왜 그런지 모르겠지만 작동하는 것 같습니다.
Saad Farooq

@flxapps, 사용자 정의보기의 경우 자식보기를 가져오고 속성을 변경하거나 리스너를 적용하는 방법은 무엇입니까? 당신의 수업에서 당신은 어떤 대화 인스턴스를 반환하지 않습니다 그리고 누군가가 자식보기를 얻으려고하면 예외가 발생할 수 있습니다
Zubair Rehman

5

@ashishduh의 답변을 약간 단순화 해 드리겠습니다.

public class AlertDialogFragment extends DialogFragment {
public static final String ARG_TITLE = "AlertDialog.Title";
public static final String ARG_MESSAGE = "AlertDialog.Message";

public static void showAlert(String title, String message, Fragment targetFragment) {
    DialogFragment dialog = new AlertDialogFragment();
    Bundle args = new Bundle();
    args.putString(ARG_TITLE, title);
    args.putString(ARG_MESSAGE, message);
    dialog.setArguments(args);
    dialog.setTargetFragment(targetFragment, 0);
    dialog.show(targetFragment.getFragmentManager(), "tag");
}

public AlertDialogFragment() {}

@NonNull
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState)
{
    Bundle args = getArguments();
    String title = args.getString(ARG_TITLE, "");
    String message = args.getString(ARG_MESSAGE, "");

    return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .create();
}

클래스의 사용자가 구성 요소의 내부에 익숙해 질 필요가 없으며 사용이 매우 간단합니다.

AlertDialogFragment.showAlert(title, message, this);

추신 : 내 경우에는 간단한 경고 대화 상자가 필요했기 때문에 내가 만든 것입니다. 예 / 아니오 또는 필요한 다른 유형에 접근 방식을 적용 할 수 있습니다.


1

간단한 예 또는 아니오 대화 상자에 대화 상자를 사용하십시오.

oncreate, request permissions 등의 수명주기를 확보해야하는보다 복잡한 뷰가 필요한 경우 모든 수명주기 재정의 대화 상자를 사용합니다. 따라서 호출 활동과 통신하지 않고 대화 상자가 작동해야하는 권한 및 기타 코드를 분리합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.