2

我正在学习使用Fragmentand DialogFragment。作为培训,我正在尝试扩展DialogFragment pageAlertDialog中给出的示例。显然一切都很好:当我显示选项菜单并单击其按钮时,会出现一个对话框,它的行为与预期一样。但是,如果在显示对话框时配置更改(例如,当我旋转屏幕时),则会正确重新创建对话框,但单击其任何按钮会使应用程序崩溃。我已经尝试了很多东西(例如,静态、、方法和其他记录在案的建议)来解决问题,但似乎没有任何效果,所以我处于起点。我正在使用支持库 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对象为空似乎很明显。

有人可以帮我吗?TIA

4

1 回答 1

2

Activity最初设置的实例dlgfshowMyDialog()配置更改时被销毁,并创建一个新实例。那个新的没有dlgf设置,所以你得到了 NPE。

getActivity()在 aFragment中将返回当前Fragment附加到的活动实例。在您的情况下,它将正确调用新实例中的方法。

要解决您的问题,您可以简单地将Fragment导致回调的原因传递给您Activity,这样您就不必存储对它的引用。

// 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);
        }
    })

另一种可能性是让您Activity保留对其MyDialogFragment使用onRetainNonConfigurationInstance()/的引用getLastNonConfigurationInstance()

于 2012-08-10T19:39:19.097 回答