Material 日期选择器自定义样式
Material Date Picker Custom Styling
我在这个库中使用了 google material 的范围日期选择器
implementation '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());
我想自定义对话框选择器更改文本字段,使对话框不是全屏等。
我怎样才能进行所有这些修改
基本上,您应该玩弄风格。在您的 AppTheme 中添加一个项目 materialCalendarTheme
,您的自定义样式继承父 ThemeOverlay.MaterialComponents.MaterialCalendar
,并更改样式。
- 更改文本字段 - 调用
MaterialDatePicker.Builder
函数 setTitleText()
- 使对话框不是全屏 - 你不能为日期范围选择器更改它,文档说它默认是全屏
Mobile date range pickers allow selection of a range of dates. They
cover the entire screen.
这是文档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>
关于全屏。
范围选择器应覆盖整个屏幕(默认 = 单个日期的对话框,范围的全屏)。
但是,您可以按照自己的风格更改此行为。
您可以使用setTheme
方法应用主题叠加:
//To apply a dialog
builder.setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar);
//To apply the fullscreen:
builder.setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar_Fullscreen);
注意: 至少需要 1.2.0-alpha01
.
版本
作为替代方案,您可以在您的应用主题中添加 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>
关于字符串.
目前没有更改字符串的方法。
唯一现有的方法是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>
在这里您可以找到 1.2.0-alpha02
中的 material 日历使用的 all the strings。
虽然发布的答案完全有效,但似乎没有必要全局设置 materialCalendarTheme
- 您可以通过 MaterialDatePicker.Builder
和 setTheme(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 对话框就不会是全屏的,而是一个普通的对话框。
在全屏和对话框版本之间切换就这么简单:
全屏:
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()
我在这个库中使用了 google material 的范围日期选择器
implementation '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());
我想自定义对话框选择器更改文本字段,使对话框不是全屏等。 我怎样才能进行所有这些修改
基本上,您应该玩弄风格。在您的 AppTheme 中添加一个项目 materialCalendarTheme
,您的自定义样式继承父 ThemeOverlay.MaterialComponents.MaterialCalendar
,并更改样式。
- 更改文本字段 - 调用
MaterialDatePicker.Builder
函数setTitleText()
- 使对话框不是全屏 - 你不能为日期范围选择器更改它,文档说它默认是全屏
Mobile date range pickers allow selection of a range of dates. They cover the entire screen.
这是文档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>
关于全屏。
范围选择器应覆盖整个屏幕(默认 = 单个日期的对话框,范围的全屏)。 但是,您可以按照自己的风格更改此行为。
您可以使用setTheme
方法应用主题叠加:
//To apply a dialog
builder.setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar);
//To apply the fullscreen:
builder.setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar_Fullscreen);
注意: 至少需要 1.2.0-alpha01
.
作为替代方案,您可以在您的应用主题中添加 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>
关于字符串.
目前没有更改字符串的方法。
唯一现有的方法是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>
在这里您可以找到 1.2.0-alpha02
中的 material 日历使用的 all the strings。
虽然发布的答案完全有效,但似乎没有必要全局设置 materialCalendarTheme
- 您可以通过 MaterialDatePicker.Builder
和 setTheme(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 对话框就不会是全屏的,而是一个普通的对话框。
在全屏和对话框版本之间切换就这么简单:
全屏:
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()