Android DialogFragment在屏幕旋转时崩溃 [英] Android DialogFragment crash on screen rotation
问题描述
但是当我旋转屏幕时,mListener变为null,并且有一个NullPointerExcpetion我点击一个按钮。我不能在活动中实现侦听器,因为它有几个这个对话框的情况,每个都有不同的动作。
CustomDialog类:
MyDialogListener mListener;
public void show(FragmentManager fm,MyDialogListener listener){
mListener = listener;
super.show(fm,MyDialog);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
返回新的AlertDialog.Builder(getActivity())
.setTitle(标题)
.setPositiveButton(android.R.string.ok,new OnClickListener(){
@Override
public void onClick(DialogInterface dialog,int whichButton){
mListener.onDialogPositiveClick ();
//屏幕旋转后的NullPointerException
}
})
.setNegativeButton(android.R.string.cancel,null)
.create() ;
}
活动类:
public void showMyFirstDialog(){
new CutsomDialog()。show(getFragmentManager(),mFirstListener);
}
public void showMySecondDialog(){
new CutsomDialog()。show(getFragmentManager(),mSecondListener);
}
Fragment
(包括 DialogFragment
)。将本地数据存储在配置更改中的机制是将片段的参数设置为包含您的数据的 Bundle
首先,消除 show()
方法;这不是正确的方法。相反,你可以这样做:
DialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString(TITLE,Dialog Title Goes Here);
args.putString(MESSAGE,这是一个对话框messaage);
frag.setArguments(args);
frag.show();
然后,您可以在创建 AlertDialog >时检索标题和消息, code>
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
Bundle args = getArguments();
String title = args.getString(TITLE);
String message = args.getString(MESSAGE);
//设置并返回警报对话框
}
处理 DialogListener
有点复杂。您不想在配置更改中持有该引用,因为它会导致被破坏的活动。相反,您可以安排从片段 onAttach()
方法中的活动中检索侦听器:
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
//现在将活动转换为您的活动类,并获得参考
//给听众
}
您可能需要更改活动类别才能使其正常工作。如果您从许多活动中使用此对话框片段,那么在此定义一个可以实现的接口来请求监听器,这是非常有用的。然后它会看起来像这样:
public interface DialogListenerProvider {
DialogListener getDialogListener();
}
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
if(activity instanceof DialogListenerProvider){
mListener =((DialogListenerProvider)activity).getDialogListener();
} else {
//抛出一个错误
}
}
I have a DialogFragment class. I have to set the listener every time it shown (It has multiple cases in my app).
But when I rotate the screen mListener becomes null and there is a NullPointerExcpetion when I click a button. I can't implement the listener in the activity because it has a few cases for this dialog, each has different action.
The CustomDialog class:
MyDialogListener mListener;
public void show(FragmentManager fm, MyDialogListener listener) {
mListener = listener;
super.show(fm, "MyDialog");
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle("Title")
.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
mListener.onDialogPositiveClick();
// NullPointerException after a screen rotate
}
})
.setNegativeButton(android.R.string.cancel, null)
.create();
}
The activity class:
public void showMyFirstDialog() {
new CutsomDialog().show(getFragmentManager(), mFirstListener);
}
public void showMySecondDialog() {
new CutsomDialog().show(getFragmentManager(), mSecondListener);
}
You cannot preserve instance fields of a Fragment
(including a DialogFragment
). The mechanism for having local data survive configuration changes is to set the fragment's arguments to a Bundle
that contains your data; this bundle will survive configuration changes.
First, eliminate the show()
method; it's not the correct approach. Instead, you can do something like this:
DialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("TITLE", "Dialog Title Goes Here");
args.putString("MESSAGE", "This is a dialog messaage");
frag.setArguments(args);
frag.show();
Then you can retrieve the title and message when you create the AlertDialog
:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle args = getArguments();
String title = args.getString("TITLE");
String message = args.getString("MESSAGE");
// set up and return the alert dialog as before
}
Dealing with the DialogListener
is a little more complex. You don't want to be holding a reference to that across config changes because it will lead back to the destroyed activity. Instead, you can arrange to retrieve the listener from the activity inside the fragment's onAttach()
method:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// now cast activity to your activity class and get a reference
// to the listener
}
You may need to change your activity class(es) a bit to get this to work right. If you're using this dialog fragment from many activities, it's particularly helpful here to define an interface that the activities can implement to request a listener. It would then look something like this:
public interface DialogListenerProvider {
DialogListener getDialogListener();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof DialogListenerProvider) {
mListener = ((DialogListenerProvider) activity).getDialogListener();
} else {
// throw an error
}
}
这篇关于Android DialogFragment在屏幕旋转时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!