【问题标题】:Can't get Android DatePickerDialog to switch to Spinner mode无法让 Android DatePickerDialog 切换到 Spinner 模式
【发布时间】:2017-06-07 16:26:23
【问题描述】:

我正在构建一个应用程序,它使用 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();
}

这是我加载对话框时的样子:

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

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

(抱歉截图。显然 SO 的解析器无法处理 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();

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

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

【问题讨论】:

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


    【解决方案1】:

    这对我有用:

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

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

    【讨论】:

    • 自定义颜色不起作用,因为您的父母来自 android: ,因此您需要在其中设置独立标签,例如:&lt;item name="android:colorAccent"&gt;@color/colorAccent&lt;/item&gt;
    • 需要 API 级别 21,所以对于那些最低级别为 19 的人来说不要去
    • 通过在&lt;item name="android:backrgound"&gt;@color/[reference to a color item]&lt;/item&gt; 项下添加&lt;item name="android:backrgound"&gt;@color/[reference to a color item]&lt;/item&gt; 设置背景颜色
    【解决方案2】:

    就像@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>
    

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

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

    对于

    在这种情况下,您可以省略指定对话框主题,因为它将由我们拥有的 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

    希望对您有所帮助! :)

    【讨论】:

      【解决方案3】:

      使用其他答案中提到的样式来获取微调器仅适用于库存(或接近库存)Android 设备,例如 Pixel、摩托罗拉、OnePlus 等。 我犯了只在这些设备上进行测试的错误,令我惊讶的是,三星用户仍然抱怨其他选择器,他们无法找到如何更改生日年份而无需逐月滚动。

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

      【讨论】:

        【解决方案4】:

        使用 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 不适用于暗模式

        【讨论】:

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