棒棒糖[微调器模式]中没有日历可视化的日期选择器对话框?
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
时,OK
和CANCEL
按钮为蓝色。我怎样才能改变这种颜色?
设置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 中删除,而且它不像你使用弃用的代码,所有这种风格正在做的是使用<item name="datePickerMode">spinner</item>
【参考方案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 的用户年份选择视图(上图),然后导航到日历视图
或显示常规日历视图,用波纹突出显示“年份按钮”(或以其他方式,例如更改年份的背景使其看起来像一个按钮)。
请参阅下面的动画,了解如何为用户看到不同的解决方案:
这是你需要的:
-
显示
DatePicker
(DatePickerDialog
或创建它的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 必须设置为微调器以显示您需要的微调器视图。
【讨论】:
以上是关于棒棒糖[微调器模式]中没有日历可视化的日期选择器对话框?的主要内容,如果未能解决你的问题,请参考以下文章