DatePickerDialog在屏幕旋转时如何保存布局

5

我有一个奇怪的问题。我有一个继承了AppCompatActivityActivity,里面包含一个 Fragment

在这个Fragment中,我展示了一个 DatePickerDialog 来选择日期。

manifest.xml中声明了一个Activity

<activity name=".SampleActivity" android:configChanges="keyboardHidden|orientation|screenLayout|screenSize" />

现在,我想在Fragment中显示DatePickerDialog,所以我创建了自定义的DatePickertFragment

public class DatePickerFragment extends AppCompatDialogFragment{
    // (...)
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day);
        return dialog;
    }
    // (...)
}

并在片段内执行show()方法

 pickerFragment.show(getChildFragmentManager(), null);

我在onClick()方法中运行显示选择器的代码,DatePicker正确显示。

但是现在有一个问题。在纵向屏幕方向下,Dialog正确显示,但是当我旋转屏幕到横向模式时,对话框似乎被剪切在左侧和右侧。我检查过,认为Dialog选择器没有在屏幕旋转时更改布局方向。以下是截图。 1. 纵向方向,正确的对话框 enter image description here

  1. 接下来我旋转设备,在横向模式下,我得到了类似于剪切对话框的东西(横向对话框布局与纵向对话框布局尺寸相同)。 enter image description here

I changed manifest.xml Activity declaration to

android:configChanges="keyboardHidden|orientation" 
And now is work correctly but I can't do this, because other app part will work incorrect. So I wonder if I can invalidate or redraw DialogPicker to resize it boundaries after I rotate screen?


1
问题在于日期和时间选择器小部件都是有意设计成这样的:如果它们在一个布局中启动,并且该活动声明它处理了方向和屏幕大小,则它将决定无法正确更改方向。我之前提出过这个问题,但 Google 似乎认为这不是问题。 https://code.google.com/p/android/issues/detail?id=199701&thanks=199701&ts=1453899881 - Marcus Hooper
简单的解决方案是,如果可以的话,不要将screenSize声明添加到清单中。 - Marcus Hooper
似乎从活动声明中删除screenSize是目前最好的解决方案。感谢提供问题报告的链接。我认为这可能是许多开发人员面临的严重问题。我花了将近一天的时间在我的应用程序中查找和修复此问题。 - Zbyszko
我发现使用“screenSize”的第二个后果。不仅日期/时间选择器受到此错误的影响,可选菜单也有错误。当我在纵向模式下首次打开菜单时,我可以看到所有菜单项,或者我可以滚动菜单项列表。但是当我旋转设备时,菜单不会变小,当菜单中有很多项目时,我无法看到所有内容,因为在横向模式下,菜单的大小与纵向模式下相同,并且滚动到菜单中间就结束了。 - Zbyszko
4个回答

3
根据Sumedh Ulhe的回答,我发现DatePicker/TimePicker将在创建时加载布局。
您可以查看android-26\android\widget\TimePicker.java
mDelegate = new TimePickerClockDelegate(

并且 android-26\android\widget\TimePickerClockDelegate.java

final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
    R.layout.time_picker_material);

有两个R.layout.time_picker_material: android-26\data\res\layout\time_picker_material.xmlandroid-26\data\res\layout-land\time_picker_material.xml

因此,当选择器已经打开时,我重新创建选择器

mCalendar = Calendar.getInstance();
...
@Override
protected void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (pickerDialog != null && pickerDialog.isShowing()) {
        pickerDialog.dismiss();
        pickerDialog = new DatePickerDialog(getContext(), (picker, year, month, 
            day) -> {
            // Do something
        }, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DATE));
        pickerDialog.show();
    }
}

感谢 @LucasHuang,如果您觉得我的回答有帮助,请点赞 :) - Sumedh Ulhe

3

使用onConfigurationChanged(Configuration newConfig)处理日历裁剪问题,检查我的代码是否与屏幕尺寸完美适配。startDateDpd是日期选择对话框,startDateTxt - 单击此日期选择对话框会打开。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if(startDateDpd!=null)
    if(startDateDpd.isVisible()){
        startDateDpd.dismiss();
        startDateTxt.performClick();
    }
}

0

使用

android:configChanges="keyboard|orientation|screenLayout"

或在该方法上进行管理:

onConfigurationChanged(Configuration newConfig)

-1

我有一个问题,与TimePicker有关。我将它放在FrameLayout中,问题得到了解决。


你能否编辑你的回答,使其直接回答原始发布的问题? - meenaparam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接