无法让Android DatePickerDialog切换到Spinner模式

时间:2017-06-07 16:26:24

标签: android android-alertdialog android-styles android-datepicker

我正在构建一个使用DatePickerDialog的应用程序,允许用户选择他们的生日。这是现在加载对话框的代码:

private void selectBirthdate() {
    int year, month, day;
    if (mBirthDate == null) {
        year = DEF_YEAR;
        month = DEF_MON;
        day = DEF_DAY;
    }
    else {
        year = mBirthDate.get(Calendar.YEAR);
        month = mBirthDate.get(Calendar.MONTH);
        day = mBirthDate.get(Calendar.DAY_OF_MONTH);
    }
    new DatePickerDialog(
            getActivity(),
            new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                    mBirthDate = new GregorianCalendar();
                    mBirthDate.set(Calendar.YEAR, year);
                    mBirthDate.set(Calendar.MONTH, month);
                    mBirthDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                    if (mTxtBirthDate != null) {
                        mTxtBirthDate.setText(mBirthDateFormat.format(mBirthDate.getTime()));
                    }
                }
            },
            year,
            month,
            day
    ).show();
}

以下是我加载对话框时的样子: Original Dialog

但是,他们希望能够使用旧式微调器DatePicker,因为在新的日历视图中,用户并不总是可以更改年份。所以我一直在研究这个主题,根据我读过的内容,应该可以使用主题强制DatePickerDialog进入Spinner模式。所以,这就是我所做的。

首先,我在styles.xml中添加了以下内容: Style XML

(对不起截图。显然SO&#s解析器无法处理XML。)

然后,我更新DatePickerDialog构造函数以使用我的新样式:

new DatePickerDialog(
        getActivity(),
        R.style.MyDialogTheme,
        new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                mBirthDate = new GregorianCalendar();
                mBirthDate.set(Calendar.YEAR, year);
                mBirthDate.set(Calendar.MONTH, month);
                mBirthDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                if (mTxtBirthDate != null) {
                    mTxtBirthDate.setText(mBirthDateFormat.format(mBirthDate.getTime()));
                }
            }
        },
        year,
        month,
        day
).show();

现在,当我加载对话框时,它看起来像这样: New Dialog

显然有些事情发生了变化;对话框的主题较暗。但它没有做我想做的事。它仍然显示日历视图而不是微调视图。知道我可能错过了什么吗?

4 个答案:

答案 0 :(得分:9)

这对我有用:

1)在style.xml中创建这两个样式

<style name="MySpinnerDatePickerStyle" parent="android:Theme.Material.Dialog">
    <item name="android:datePickerStyle">@style/MySpinnerDatePicker</item>
</style>

<style name="MySpinnerDatePicker" parent="android:Widget.Material.DatePicker">
    <item name="android:datePickerMode">spinner</item>
</style>

2)在新的DatePickerDialog中将“MySpinnerDatePickerStyle”设置为您的样式

DatePickerDialog datePickerDialog = new DatePickerDialog(myContext, R.style.MySpinnerDatePickerStyle, date, myCalendar
                    .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
                    myCalendar.get(Calendar.DAY_OF_MONTH));

希望这对你有用.. 注意:我仍在尝试通过更改颜色和文本颜色来确定如何设置微调器的样式

答案 1 :(得分:1)

就像@Abuzaid所说的那样,在您的AppTheme样式内,添加android:datePickerStyle项目,如下面的AppTheme示例所示:

 <!-- Example of a Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorPrimary</item>

    <!-- !Important! Add this to force the use of the Spinner mode -->
    <item name="android:datePickerStyle">@style/myDatePickerStyle</item>
</style>

将此样式添加到您的styles.xml中(在values-v21文件夹内,因为此选项仅适用于api 21 +)

<style name="myDatePickerStyle" parent="android:Widget.Material.DatePicker">
    <item name="android:datePickerMode">spinner</item>
</style>

对于Android版本<21,微调器模式是默认设置。对于21岁以上的人群,日历模式是新的默认模式。

在这种情况下,可以省略指定对话框主题,因为它将由我们拥有的AppTheme推断出来。例如:(使用Java 8 lambda)

final Calendar cal = Calendar.getInstance();
final DatePickerDialog.OnDateSetListener dateSelectedListener = (view, year, monthOfYear, dayOfMonth) -> {
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, monthOfYear+1);
    cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
 };

int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);

DatePickerDialog dp= new DatePickerDialog(context, dateSelectedListener, year, month, day);

参考:https://developer.android.com/reference/android/app/DatePickerDialog

希望可以提供帮助! :)

答案 2 :(得分:0)

使用其他答案中提到的样式来获取微调器仅适用于库存(或接近库存)Android设备,例如Pixel,Motorola,OnePlus等。 我错误地只在这些设备上进行测试,令我惊讶的是,三星用户仍在抱怨另一个选择器,他们无法在不必逐月滚动的情况下找到如何更改生日年。

唯一的交叉设备解决方案是使用库,这样您就可以确保获得相同的微调器选择器,而不管底层操作系统如何。我的情况是,我使用了SpinnerDatePicker,这是原生选择器的一个非常简单的替代品。

答案 3 :(得分:0)

使用Material Componente的简单解决方案

<style name="SpinnerDatePickerDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog">
    <item name="android:datePickerStyle">@style/DatePickerStyle</item>
    <item name="colorControlNormal">@color/teal_200</item>
</style>

<style name="DatePickerStyle" parent="@android:style/Widget.Material.Light.DatePicker">
    <item name="android:datePickerMode">spinner</item>
</style>

出于某些原因,ThemeOverlay.MaterialComponents.Dialog.Alert无法在暗模式下使用