旋转时调用 DatePickerDialog onDateSet

Posted

技术标签:

【中文标题】旋转时调用 DatePickerDialog onDateSet【英文标题】:DatePickerDialog onDateSet called when rotated 【发布时间】: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");

【问题讨论】:

看看setRetainInstance() 我说的对吗?您不想在屏幕旋转时调用 dateset 方法 自从在此问题上发布赏金后,我发现它与 ***.com/questions/11444238/… 重复,但由于我的赏金,我无法投票关闭它。 【参考方案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 方法中)。

【讨论】:

以上是关于旋转时调用 DatePickerDialog onDateSet的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 8 splitviewcontroller 主视图控制器不会在旋转时调整高度

在片段中显示 DatePickerDialog

转换子视图时调用的 UIViewController viewDidLayoutSubviews

CollectionView 标头不会在自动旋转时调整大小

使用 Transform 旋转时调整 UIView 的大小

UIPageViewController 没有在旋转时调整其子视图控制器的大小