49

ユーザーがログインできるアプリの実装 次のような状況があります。ユーザーがログインしている場合はアクションを実行し、そうでない場合は結果のログイン アクティビティを開始し、結果が Activity.RESULT_OK の場合はアクションを実行します。

私の問題は、実行するアクションがDialogFragmentを表示することですが、呼び出し

DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
newFragment.show(ft, "dialog")

onActivityResult コールバックで例外をスローします。

Caused by: java.lang.IllegalStateException:  
Can not perform this action after onSaveInstanceState

では、どうすればこれを解決できますか?そこでフラグを立ててonResumeでダイアログを表示することを考えていますが、このソリューションは少し汚いと思います

編集:さらにコードを追加しました(DialogFragmentを表示するためにこの例に従っています

ユーザーがアクションを要求した場合:

... 
if (!user.isLogged()){
 startActivityForResult(new Intent(cnt, Login.class), REQUEST_LOGIN_FOR_COMMENT);
}

同じフラグメント内

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_LOGIN_FOR_COMMENT && resultCode == Activity.RESULT_OK) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        DialogFragment newFragment = MyDialogFragment.newInstance();
        newFragment.show(ft, "dialog")
    }
}

また、ユーザーがログイン アクティビティ コールにログインした場合。

setResult(Activity.RESULT_OK);
finish();
4

8 に答える 8

102

私が思いついた最善のことは、 .show() を使用せずにこれを行うことです。

CheckinSuccessDialog dialog = new CheckinSuccessDialog();
//dialog.show(getSupportFragmentManager(), null);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(dialog, null);
ft.commitAllowingStateLoss();
于 2012-09-17T18:11:17.680 に答える
14

これが私にとってうまくいく回避策です。

private void alert(final String message) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        public void run() {
            AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance(message);
            alertDialogFragment.show(getFragmentManager(), ALERT_DIALOG_FRAGMENT);
        }
    });        
}
于 2013-05-31T14:11:45.310 に答える
4

DialogFragment を使用している場合、dissmissAllowingStateLoss() で Fragment を却下するだけでうまくいきました。

于 2014-02-11T12:15:56.283 に答える
4

アクティビティが破棄されているかどうかを確認するだけです。

if (!getActivity().isFinishing()) {
    DialogFragment fragment = MyFragment.newInstance();
    fragment.show(getActivity().getSupportFragmentManager(), MyFragment.TAG);
}

https://stackoverflow.com/a/41813953/2914140も参照してください。書面でDialogFragment

override fun show(manager: FragmentManager?, tag: String?) {
    try {
        val ft = manager?.beginTransaction()
        ft?.add(this, tag)
        ft?.commitAllowingStateLoss()
    } catch (ignored: IllegalStateException) {
    }
}
于 2016-09-24T20:21:40.840 に答える
2

リフレクションによってshow(Fragment manager, String tag)状態を失い、元の関数から変更できるように関数をオーバーライドします。mDismissed = false; mShownByMe = true;

public class DialogParent extends DialogFragment {

    @Override
    public void show(FragmentManager manager, String tag) {
        try {
            Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
            Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
            mDismissed.setAccessible(true);
            mShownByMe.setAccessible(true);
            mDismissed.setBoolean(this, false);
            mShownByMe.setBoolean(this, true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    }
}
于 2016-12-12T07:59:21.090 に答える