物料日期选择器自定义样式

时间:2019-12-10 10:36:00

标签: android material-design android-datepicker material-components material-components-android

我已将该库中的Google材料用于范围日期选择器

  

实现'com.google.android.material:material:1.2.0-alpha02'

这是我的代码

     MaterialDatePicker.Builder<Pair<Long, Long>> builder =
            MaterialDatePicker.Builder.dateRangePicker();

    CalendarConstraints.Builder constraintsBuilder = new CalendarConstraints.Builder();
    builder.setCalendarConstraints(constraintsBuilder.build());
    MaterialDatePicker<Pair<Long,Long>> picker = builder.build();
    assert getFragmentManager() != null;
    picker.show(getFragmentManager(), picker.toString());

我想自定义对话框选择器更改文本字段,使对话框不全屏显示等。 我该如何进行所有修改

enter image description here

4 个答案:

答案 0 :(得分:4)

在全屏和对话框版本之间切换很容易:

全屏

val picker = MaterialDatePicker.Builder.dateRangePicker().setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar_Fullscreen).build()

对话框

val picker = MaterialDatePicker.Builder.dateRangePicker().setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar).build()

答案 1 :(得分:2)

关于全屏

范围选择器应覆盖整个屏幕。
但是,您可以在样式中更改此行为。

在您的应用主题中添加 materialCalendarFullscreenTheme 属性。

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
   <item name="materialCalendarFullscreenTheme">@style/CustomThemeOverlay_MaterialCalendar_Fullscreen</item>
</style>

其中:

  <style name="CustomThemeOverlay_MaterialCalendar_Fullscreen"
      parent="@style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen">
    <item name="materialCalendarStyle">@style/Custom_MaterialCalendar.Fullscreen</item>
  </style>

您可以在此处使用 android:windowFullscreen 属性覆盖该值:

  <style name="Custom_MaterialCalendar.Fullscreen"
      parent="@style/Widget.MaterialComponents.MaterialCalendar.Fullscreen">
    <item name="android:windowFullscreen">false</item>
  </style>

enter image description here

关于字符串
当前没有更改字符串的方法。
现有的唯一方法是 builder.setTitleText 来更改标题。

但是,您可以覆盖项目中所有现有的字符串,但是此替代方法可以停止,以便在下一发行版中运行。 例如:

  <string name="mtrl_picker_save" description="Confirms the selection [CHAR_LIMIT=12]">....</string>
  <string name="mtrl_picker_text_input_date_range_start_hint" description="Label for the start date in a range selected by the user [CHAR_LIMIT=60]">...</string>
  <string name="mtrl_picker_text_input_date_range_end_hint" description="Label for the end date in a range selected by the user [CHAR_LIMIT=60]">...</string>

enter image description here

在这里您可以在1.2.0-alpha02中找到材料日历使用的all the strings

答案 2 :(得分:1)

基本上,您应该使用样式。在您的AppTheme中,添加具有自定义样式的项materialCalendarTheme,该项继承父项ThemeOverlay.MaterialComponents.MaterialCalendar,然后更改样式。

  1. 更改文本字段-调用MaterialDatePicker.Builder函数setTitleText()
  2. 使对话框不全屏显示-您不能为日期范围选择器更改它,文档显示默认为全屏显示
  

移动日期范围选择器允许选择日期范围。他们   覆盖整个屏幕。

这里的文档https://material.io/components/pickers

以下是我调整一些颜色以匹配主题的方法:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    <item name="materialCalendarTheme">@style/ThemeMaterialCalendar</item>
</style>

<style name="ThemeMaterialCalendar" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
    <item name="buttonBarPositiveButtonStyle">@style/ThemeMaterialCalendarButton</item>
    <item name="buttonBarNegativeButtonStyle">@style/ThemeMaterialCalendarButton</item>
    <item name="materialButtonStyle">@style/ThemeMaterialCalendarTextButton</item>
</style>

<style name="ThemeMaterialCalendarButton" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
    <item name="android:textColor">?themeTextColorPrimary</item>
</style>

<style name="ThemeMaterialCalendarTextButton" parent="Widget.MaterialComponents.Button.TextButton.Dialog.Flush">
    <item name="android:textColor">?themeTextColorPrimary</item>
    <item name="iconTint">?themeTextColorPrimary</item>
</style>

答案 3 :(得分:1)

虽然已发布的答案完全有效,但似乎无需全局设置materialCalendarTheme-您可以通过MaterialDatePicker.BuildersetTheme(int themeResId)方法将其设置为。以下是他们如何在Material Design Catalog App中进行操作的示例。

val datePicker = MaterialDatePicker.Builder.dateRangePicker().apply {
    context?.resolveOrNull(R.attr.materialCalendarTheme)?.let {
        setTheme(it)
    }
    setCalendarConstraints(getConstraints())
    }.build()
// ...

resolveOrThrow 辅助方法:

fun Context.resolveOrNull(@AttrRes attributeResId: Int): Int? {
    val typedValue = TypedValue()
    if (theme.resolveAttribute(attributeResId, typedValue, true)) {
        return typedValue.data
    }
    return null
}

这样,DatePicker对话框将不会全屏显示,而是常规对话框。