【问题标题】:DatePickerDialog onDateSet called when rotated旋转时调用 DatePickerDialog onDateSet
【发布时间】:2012-12-07 04:55:44
【问题描述】:

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

我的 DialogFragment

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

【问题讨论】:

标签: android android-fragments android-lifecycle


【解决方案1】:

onDateSet方法中,使用Activity::isChangingConfigurations检查Activity是否因配置更改而重启。如果是,则不要显示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();
    }
}

我已经对其进行了测试并且运行良好。如果需要任何进一步的帮助,请告诉我。

【讨论】:

  • 这仅适用于配置更改,但当用户通过返回键关闭DatePickerDialog 时,onDateSet 也会被调用。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    DatePickerDialog的实现方式是,如果OnDateSetListener被注册,它会通知DataSetonStop的变化。

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

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

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

    自定义 DatePickerDialog

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

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

    【讨论】:

      【解决方案4】:

      尝试换行

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

      通过

      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
           super.onCreateDialog(savedInstanceState);
       }
      

      【讨论】:

        【解决方案5】:

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

        android:configChanges="keyboardHidden|orientation"
        

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2012-09-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多