8

我正在使用 DialogFragment 在 onCreateDialog() 中返回 DatePickerDialog。我已将 dateSetListener 设置为 DialogFragment (在下面的示例中为“this”),除了在屏幕旋转发生时调用 onDateSet() 之外,一切正常,这是不可取的。如何在屏幕旋转时不调用 onDateSet?

我的对话片段

public static class DateDialogFragment extends DialogFragment implements
DatePickerDialog.OnDateSetListener{

    public static DateDialogFragment newInstance() {
        return new DateDialogFragment();
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new DatePickerDialog(getActivity(), this, 2012, 11, 19);
    }

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear,
        int dayOfMonth) {
        //This is called when screen rotated, which I dont want
        Toast.makeText(getActivity(), "Year: "+year+" Month: "+monthOfYear+" Day: "+dayOfMonth, Toast.LENGTH_SHORT).show();
    }

}

这就是我所说的

if(getActivity()!=null){
    FragmentManager fm = getActivity().getSupportFragmentManager();
    DialogFragment newFragment = DateDialogFragment.newInstance();
    newFragment.show(fm, "dialog");
}
4

6 回答 6

9

onDateSet方法中,使用Activity::isChangingConfigurationsActivity检查是否因配置更改而重新启动。如果是,则不显示.Toast

@Override
public void onDateSet(android.widget.DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    if( ! this.getActivity().isChangingConfigurations() ) {
        // Dialog is dismissed by user explicitly, hence show the Toast message.       
        Toast.makeText(getActivity(), "Year: "+year+" Month: "+monthOfYear+" Day: "+dayOfMonth, Toast.LENGTH_SHORT).show();
    }
}

我已经对其进行了测试并且可以完美运行。让我知道是否需要任何进一步的帮助。

于 2014-04-24T13:55:00.350 回答
3

您可以尝试在对话框的附加/分离回调中使用标志。这个想法是在对话框尚未附加到窗口时取消侦听器的任何触发(因此更改不可能来自用户),例如恢复(我认为这是再次调用侦听器的原因):

// a field in the DateDialogFragment
private boolean mShouldBeCanceled = true; // cancel the listener when this is true(the default)

//...
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
     return new DatePickerDialog(getActivity(), this, 2012, 11, 19) {

                @Override
                public void onAttachedToWindow() {
                    mShouldBeCanceled = false;
                }

                @Override
                public void onDetachedFromWindow() {
                    mShouldBeCanceled = true;
                }
     };
}

并在侦听器中使用标志(由于侦听器仅在构造函数中初始化):

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
    int dayOfMonth) {
    if (mShouldBeCanceled) {
            return; // not a valid listener triggering
    }
    //This is called when screen rotated, which I dont want
    Toast.makeText(getActivity(), "Year: "+year+" Month: "+monthOfYear+" Day: "+dayOfMonth, Toast.LENGTH_SHORT).show();
}
于 2014-04-24T16:08:59.573 回答
2

实现的方式是,如果已注册DatePickerDialog,它将通知DataSet更改。onStopOnDateSetListener

您还可以看到在显示onDateSet时按下后退键时调用DatePickerDialog(不仅是方向)

原因,当您创建DatePickerDialog实例时,您已经注册了回调监听器。

所以最好的方法是创建一个custom Dialog扩展DatePickerDialog并覆盖onStop

自定义日期选择器对话框

  private static class CustomDatePickerDialog extends DatePickerDialog{

    public CustomDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
        super(context, callBack, year, monthOfYear, dayOfMonth);
    }

    @Override
    protected void onStop() {
        return;
    }
}

最后,更改CreateDialog

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new CustomDatePickerDialog(getActivity(), this, 2012, 11, 19);
    }

这应该可以完美地工作。如果您发现任何问题,请告诉我。

于 2014-04-30T01:06:39.347 回答
1

尝试更换线路

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
         return new DatePickerDialog(getActivity(), this, 2012, 11, 19);
    }

经过

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
     super.onCreateDialog(savedInstanceState);
 }
于 2014-04-29T18:32:35.450 回答
0

将此属性添加到清单中的活动

android:configChanges="keyboardHidden|orientation"
于 2014-04-30T20:43:58.023 回答
-1

当屏幕旋转时,活动被销毁并重新创建,每次都会创建一个新片段。避免此问题的一种方法是更改​​代码中 if(getActivity()!=null) 语句的位置。将其放置在不受活动娱乐影响的地方(不在 OnCreate 方法中)。

于 2012-12-19T19:23:55.407 回答