2

私は使い方Fragmentを学んでいますDialogFragmentトレーニングとして、DialogFragmentページAlertDialogに示されている例を拡張しようとしています。どうやらすべてが正常です。オプションメニューを表示してそのボタンをクリックすると、ダイアログが表示され、期待どおりに動作します。ただし、ダイアログが表示されているときに構成が変更された場合(たとえば、画面を回転させた場合)、ダイアログは正しく再作成されますが、そのボタンのいずれかをクリックするとアプリケーションがクラッシュします。私は問題を修正するために多くのこと(たとえば、静的、、メソッド、およびその他の文書化された提案)を試しましたが、何も機能していないようですので、私は出発点にいます。サポートライブラリv4を使用しています。newInstancesetRetainInstanceonSaveInstanceState

これが私の主なアクティビティコードです。

public class MainActivity extends FragmentActivity {
    private MyDialogFragment dlgf;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        showMyDialog();
        return true;
    }

    private void showMyDialog(){
        dlgf = MyDialogFragment.newInstance();
        dlgf.show(getSupportFragmentManager(), "dialog");
    }

    public void doPositive() {
        // do stuff...
        dlgf.getDialog().dismiss();
    }

    public void doNegative() {
        // Cancel button pressed
        dlgf.getDialog().dismiss();
    }
}

これが私のDialogFragmentコードです:

public class MyDialogFragment extends DialogFragment {
    private View view;

    public static MyDialogFragment newInstance() {
        MyDialogFragment dlgf = new MyDialogFragment();
        return dlgf;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        view = getActivity().getLayoutInflater().inflate(R.layout.alertdialog, null);

        return new AlertDialog.Builder(getActivity())
        .setView(view)
        .setTitle("A Title")
        .setPositiveButton("OK",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int buttonID) {
                    ((MainActivity)getActivity()).doPositive();
                }
            })
        .setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int buttonID) {
                    ((MainActivity)getActivity()).doNegative();
                }
            })
        .create();
    }

}

[キャンセル]ボタンをクリックした後に実行がクラッシュすると、logcatNullPointerExceptionはdoNegativeメソッドにを表示します。[OK]ボタンをクリックした後にクラッシュが発生したNullPointerException場合は、doPositiveメソッドで発生します。DialogFragmentオブジェクトがnullであることは明らかです。

誰か助けてくれませんか?TIA

4

1 に答える 1

2

最初に設定されたインスタンスActivityは、構成の変更時に破棄され、新しいインスタンスが作成されます。その新しいものは設定されていないので、NPEを取得します。dlgfshowMyDialog()dlgf

getActivity()の中には、が接続されFragmentている現在のアクティビティインスタンスが返されますFragment。あなたの場合、それは新しいインスタンスのメソッドを正しく呼び出します。

To solve your problem you could simply pass the Fragment that caused the callback to your Activity so you don't have to store a reference to it.

// in activity
public void doPositive(MyDialogFragment source) {
    // do stuff...
    source.getDialog().dismiss();
}

// in dialog fragment  
.setPositiveButton("OK",
    new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int buttonID) {
            ((MainActivity)getActivity()).doPositive(MyDialogFragment.this);
        }
    })

Another possibility is to let your Activity retain the reference to its MyDialogFragment using onRetainNonConfigurationInstance() / getLastNonConfigurationInstance().

于 2012-08-10T19:39:19.097 に答える