棒棒糖[微调器模式]中没有日历可视化的日期选择器对话框?

Posted

技术标签:

【中文标题】棒棒糖[微调器模式]中没有日历可视化的日期选择器对话框?【英文标题】:Datepicker dialog without calendar visualization in lollipop [spinner mode]? 【发布时间】:2015-04-28 17:22:39 【问题描述】:

我阅读了文档:http://developer.android.com/guide/topics/ui/controls/pickers.html 但是现在在棒棒糖中出现了日历(对于一个事件来说可以,但对于设置出生日期来说很糟糕,我会使用微调模式。)我无法删除它! 在布局中使用这个属性很容易:

 <DatePicker
 datePickerMode="spinner"...>

但如果我尝试设置,则来自 DatePickerDialog 的代码

dialogDatePicker.getDatePicker().setSpinnersShown(true);
dialogDatePicker.getDatePicker().setCalendarViewShown(false); 

这些属性不起作用,日历继续出现!

public static class MyDatePicker extends DialogFragment implements DatePickerDialog.OnDateSetListener 
        int pYear;
        int pDay;
        int pMonth;

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) 
            // Use the current date as the default date in the picker
            final Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH);
            int day = c.get(Calendar.DAY_OF_MONTH);
            DatePickerDialog dialogDatePicker = new DatePickerDialog(getActivity(), this, year, month, day);
            dialogDatePicker.getDatePicker().setSpinnersShown(true);
            dialogDatePicker.getDatePicker().setCalendarViewShown(false);
            return dialogDatePicker;
            // Create a new instance of DatePickerDialog and return it
            //return new DatePickerDialog(getActivity(), this, year, month, day);
        

        public void onDateSet(DatePicker view, int year, int month, int day) 
            pYear = year;
            pDay = day;
            pMonth = month;
        
    

【问题讨论】:

尝试将android:calendarViewShown="false" 放入xml 这是重复的:在此处查看答案:***.com/a/31610267/1887635 【参考方案1】:

DatePickerDialog 使用您的活动主题指定的对话框主题。这是一个完全指定的主题,这意味着您需要重新指定您在活动主题中设置的任何属性(例如日期选择器样式)。

<style name="MyAppTheme" parent="android:Theme.Material">
    <item name="android:dialogTheme">@style/MyDialogTheme</item>
    <item name="android:datePickerStyle">@style/MyDatePicker</item>
</style>

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

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

注意:由于Issue 222208,这在Android N / API 24 中将不起作用。它已经在下一个版本的平台中修复。 API 24 设备没有可用的解决方法。

【讨论】:

只有这样才能在片段中起作用,谢谢。现在来弄清楚如何使它在 api v21 下和之上都工作。 @alanv 当我将上述MyDialogTheme 应用于DatePickerDialog 时,OKCANCEL 按钮为蓝色。我怎样才能改变这种颜色? 设置colorAccent,就像在活动主题上一样。 主题应该扩展 android:Theme.Material.Dialog.Alert(或 Light 变体),否则对话框只会包裹微调器的宽度。 @Mukesh 与code.google.com/p/android/issues/detail?id=222208 相同的问题。它已在未来的版本中修复,但对话框没有解决方法。【参考方案2】:

在代码级别应用 Holo_theme 为我工作。

new DatePickerDialog(getActivity(),android.R.style.Theme_Holo_Dialog,this, year,month, day);

【讨论】:

很好的答案! android.R.style.Theme_Holo_Light_Dialog 看起来好多了 @WaqasRaja 同样的问题..你找到解决办法了吗? 正如上面 cmets 中提到的,它不适用于 API 24,但它适用于较旧的 API 级别。谁能告诉如何使它在 API 24 上工作? android.R.style.Theme_Holo_Dialog 现已弃用 它仍然适用于我的 API 25。不知道为什么 API 24 是一次性问题。关于弃用,是的,它已被弃用,你不应该使用 Holo 主题,但他们不太可能将其从 SDK 中删除,而且它不像你使用弃用的代码,所有这种风格正在做的是使用&lt;item name="datePickerMode"&gt;spinner&lt;/item&gt;【参考方案3】:

我认为这个问题的最佳解决方案是在 XML 文件中定义一个新样式,然后在代码中以编程方式使用它。

虽然@alanv answer 非常完美并且可以正常工作,但它的问题是它将应用于所有日期选择器。假设您有一个 DatePicker 需要显示日历视图,而另一个 DatePicker 需要显示微调器视图,这将不起作用。

所以在styles.xml 中定义一个新的样式。在名为 values-v21 的文件夹中创建此文件(请参阅命名结构 here),因为这些属性仅在棒棒糖后引入。在棒棒糖之前,只有微调模式。

 <style name="CustomDatePickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
    <item name="android:datePickerStyle">@style/MyDatePickerStyle</item>
</style>

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

最后,像这样在代码中使用它

DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(),
    R.style.CustomDatePickerDialogTheme, this, year, month, day);
return datePickerDialog;

【讨论】:

您还应该在 values 文件夹中的 style.xml 中提供相应的条目。否则 DatePicker 在棒棒糖之前的设备上的样式错误。【参考方案4】:

您可以使用库来创建旧的“微调器”样式 DatePicker,它只是三个 NumberPicker 放在一起:

https://github.com/drawers/SpinnerDatePicker

首先,定义一个样式:

<style name="NumbePickerStyle">
    <item name="android:textSize">22dp</item>
    <item name="android:textColorPrimary">@color/colorAccent</item>
    <item name="android:colorControlNormal" tools:targetApi="lollipop">@color/colorAccent</item>
</style>

那么,

new SpinnerDatePickerDialogBuilder()
        .context(MainActivity.this)
        .callback(MainActivity.this)
        .spinnerTheme(spinnerTheme)
        .year(year)
        .monthOfYear(monthOfYear)
        .dayOfMonth(dayOfMonth)
        .build()
        .show();

免责声明:我是这个库的作者

【讨论】:

【参考方案5】:

添加属性calendarViewShown并设置为false:

<DatePicker
android:layout_
android:layout_
android:id="@+id/date_field"
android:calendarViewShown="false"/>

【讨论】:

【参考方案6】:

这个答案有点离题,但提供了一种标准 DatePicker 的替代方法,这可能对某人有用。 现在是 2019 年,这个问题仍然存在。

android:datePickerMode="spinner" 不适用于所有 API 为如此简单的任务集成一个库(拥有相当不错的材料选择器)并不是每个开发人员都想要的。

从另一个角度来看,这个小部件非常方便,问题是不是所有的Android用户都知道他们可以打开年份选择部分,这使得年份选择变得容易:

这对一些用户来说并不是最好的用户体验,他们很难选择出生日期(一些用户只是滑动日历直到达到所需的年份)

我最终得到了一个解决方案,它允许执行以下操作之一:

    首先显示 DatePicker 的用户年份选择视图(上图),然后导航到日历视图 或显示常规日历视图,用波纹突出显示“年份按钮”(或以其他方式,例如更改年份的背景使其看起来像一个按钮)。

请参阅下面的动画,了解如何为用户看到不同的解决方案:

这是你需要的:

    显示DatePickerDatePickerDialog 或创建它的DialogFragment)。

    检索“年份”TextView

    val yearTextview =dialog.findViewById<TextView>(context.resources
    ?.getIdentifier("android:id/date_picker_header_year", null, null)?: -1)
    

    用它做任何你想做的事,例如:

    以编程方式执行单击以选择年份部分:

    yearTextview?.performClick()

    显示后显示波纹效果(设置yearTextview?.isPressed = true一段时间)

    更改背景等

缺点:如果 id 将在下一个 API 中更改 - 这将需要您相应地更改它

【讨论】:

这是一种出色的方法,与 OP 想要的并不完全匹配,但可能是最佳的整体解决方案。【参考方案7】:

你可以试试这个

DatePickerDialog dialogDatePicker = new DatePickerDialog(getActivity(), this, year, month, day);
            dialogDatePicker.getDatePicker().setCalendarViewShown(false);
            return dialogDatePicker;

删除

dialogDatePicker.getDatePicker().setSpinnersShown(true);

【讨论】:

这些调用现已被弃用【参考方案8】:

试试这个它对我有用,做一个自定义的 datelistener:

    @SuppressWarnings("deprecation")
    public void setDate(View view) 
        showDialog(999);
    

    @SuppressWarnings("deprecation")
    protected Dialog onCreateDialog(int id) 
        // TODO Auto-generated method stub
        if (id == 999) 
            return new DatePickerDialog(this, myDateListener, year, month-1, day);
        
        return null;
    
    //THIS
    private DatePickerDialog.OnDateSetListener myDateListener= new DatePickerDialog.OnDateSetListener() 

        @Override
        public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) 

            showDate(arg1, arg2+1, arg3);
        
    ;

    private void showDate(int year, int month, int day) 

        //dateView.setText(new StringBuilder().append(day).append("-")
               // .append(month).append("-").append(year));
    

【讨论】:

嗯,我会尝试......但现在我正在使用没有对话框的日期选择器。【参考方案9】:

抛开所有花哨的东西,使用带有“int 主题”参数的 DatePickerDialog 构造函数。 没有它,它似乎默认为将其设置为 CalendarView 模式的任何 int 。 使用小整数(0、1、2、3...),它会给你一个微调器(至少在我在模拟器上运行的 API 19 应用程序中)。 基本上,试试 new DatePickerDialog(getContext(), 0, this, year, month, day) 注意那里的 0(或 1,或 2 等)

注意: 我不确定是否有静态主题字段的列表,并且使用硬编码的“0”而不是“Theme.HOLO_LIGHT”或任何可能在不同设备上产生影响的东西,但它以某种方式完成了工作。

【讨论】:

【参考方案10】:

API 级别 24 已弃用与显示微调器和/或日历视图相关的 DatePicker 方法。方法 setSpinnersShown(boolean shown) 和 setCalendarViewShown(boolean shown) 已弃用,因为日历模式材料样式不支持该功能。

如果您想在微调器模式下使用材质样式,请使用 DatePicker 小部件。

将以下样式应用于您的日期选择器 xml 元素以获取材质微调器。有关日期选择器和样式的更多信息,请参阅http://www.zoftino.com/android-datepicker-example。

<style name="MyDatePickerSpinnerStyle" parent="@android:style/Widget.Material.DatePicker">
    <item name="android:datePickerMode">spinner</item>
    <item name="android:calendarViewShown">false</item>
    <item name="colorControlNormal">#d50000</item>
</style>

【讨论】:

不确定它是否在您发布此内容后发生了变化,但您可以在 xml 文件中执行 android:calendarViewShown="false",在该文件中,您在 DatePicker 其他属性旁边声明了 DatePicker【参考方案11】:
<DatePicker
    android:id="@+id/datePicker"
    android:layout_
    android:layout_
    android:calendarViewShown="false"
    android:datePickerMode="spinner"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:theme="@style/NumberPickerStyle"
    tools:targetApi="lollipop" />

在对话框中填充它,你就完成了。尽管android:datePickerMode 可能会向您显示 API 21 和高警告,但它应该也可以在早期版本的 android 中工作,因为 DatePicker 样式本身是一种旧样式。我在 API 16 及更高版本中测试了这个实现,没有遇到任何问题。

代码:

private fun showOldDatePickerDialog() 
    with(View.inflate(this, R.layout.old_style_date_picker, null))
        AlertDialog.Builder(context)
                .setView(this)
                .setPositiveButton("Ok")  _, _ ->
                    Log.d("DatePicker","$this.datePicker.month.plus(1) : $this.datePicker.dayOfMonth : $this.datePicker.year")
                .create().also  it.show() 
    

要更改文本大小,请将其添加到您的样式中。

<style name="NumberPickerStyle">
    <item name="android:textSize">21sp</item>
</style>

【讨论】:

【参考方案12】:

第 1 步:创建微调器/日历日期选择器布局

.../main/res/layout/spinner_date_picker_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/datePicker"
        android:layout_
        android:layout_
        android:datePickerMode="spinner"
        android:calendarViewShown="false" />

.../main/res/layout/calendar_date_picker_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/datePicker"
        android:layout_
        android:layout_
        android:datePickerMode="calendar" />

第 2 步:在 TextView 上设置可点击行为以显示日期对话框。

.../main/res/layout/activity_layout.xml

    <TextView
        android:id="@+id/dateText"
        android:layout_
        android:layout_
        android:layout_margin="5dp"
        android:clickable="true"
        android:text="Date"
        android:onClick="@() -> viewModel.onClickDate()"></TextView>

第 3 步:在 onClickDate 上显示对话框

override fun onClickDate() 
        showDialogForDate()

第 4 步:将 DatePicker 布局设置为对话框视图。

private fun showDialogForDate() 

    //Set spinner/calendar date picker layout
    val spinnerDatePicker = layoutInflater.inflate(R.layout.spinner_date_picker_layout, null)

    // On click listener for dialog buttons
    val dialogClickListener = DialogInterface.OnClickListener  _, which ->
        when (which) 
            DialogInterface.BUTTON_POSITIVE -> 
                activity!!.dateText.text = spinnerDatePicker.datePicker.dayOfMonth.toString() + "/" + (spinnerDatePicker.datePicker.month + 1) + "/" + spinnerDatePicker.datePicker.year
            
            DialogInterface.BUTTON_NEGATIVE -> 

            
        
    

    val builder = AlertDialog.Builder(context!!)
    builder.setTitle(resources.getString(R.string.dialog_title))
        .setView(spinnerDatePicker)
        .setPositiveButton("Ok", dialogClickListener)
        .setNegativeButton("Cancel", dialogClickListener)
        .create()
        .show()

【讨论】:

【参考方案13】:
<DatePicker
    android:calendarViewShown="false"
    android:layout_
    android:layout_
    android:datePickerMode="spinner"/>

calendatViewShown 将删除日历视图,并且 dataPickerMode 必须设置为微调器以显示您需要的微调器视图。

【讨论】:

以上是关于棒棒糖[微调器模式]中没有日历可视化的日期选择器对话框?的主要内容,如果未能解决你的问题,请参考以下文章

没有日历可视化的 ASP.NET Datepicker

datepickerdialog 隐藏日历并将我的日期选择器视图更改为标准模式

你如何让剑道日期选择器对最短日期进行日期验证?

剑道日期选择器随机不显示日历以更改日期

Excel中进行插入日期选择器的操作技巧

power BI OTD不同的日期如何设置report 时间