Material Date Picker Custom Styling - android

i have used range date picker from google material with this library
implementation 'com.google.android.material:material:1.2.0-alpha02'
this is my code
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());
i want to custom the dialog picker change text field,make dialog not full screen etc..
how can i make all this modifications

About the fullscreen.
The range picker should cover the entire screen (default = dialog for single date, fullscreen for range).
However you can change this behavior in your style.
You can use the setTheme method to apply a theme overlay:
//To apply a dialog
builder.setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar);
//To apply the fullscreen:
builder.setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar_Fullscreen);
Note: it requires at least the version 1.2.0-alpha01.
As alternative you can add in your app theme the materialCalendarFullscreenTheme attribute.
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="materialCalendarFullscreenTheme">#style/CustomThemeOverlay_MaterialCalendar_Fullscreen</item>
</style>
where:
<style name="CustomThemeOverlay_MaterialCalendar_Fullscreen"
parent="#style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen">
<item name="materialCalendarStyle">#style/Custom_MaterialCalendar.Fullscreen</item>
</style>
Here you can override the value with the android:windowFullscreen attribute:
<style name="Custom_MaterialCalendar.Fullscreen"
parent="#style/Widget.MaterialComponents.MaterialCalendar.Fullscreen">
<item name="android:windowFullscreen">false</item>
</style>
About the strings.
Currently there isn't a method to change the strings.
The only existing method is builder.setTitleText to change the title.
However you can override all the existing strings in your project, but this workaround can stop to run in the next releases.
For example:
<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>
Here you can find all the strings used by the material calendar in the 1.2.0-alpha02.

Basically, you should play with styles. In your AppTheme add an item materialCalendarTheme with your custom style that inherits parent ThemeOverlay.MaterialComponents.MaterialCalendar, and change the style.
Change text field - call MaterialDatePicker.Builder function setTitleText()
Make dialog not full screen - you can't change it for date range picker, the documentation says that it is fullscreen by default
Mobile date range pickers allow selection of a range of dates. They
cover the entire screen.
Here's documentation https://material.io/components/pickers
Here's how I tweaked some colors to match my theme:
<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>

Changing between fullscreen and dialog version can be as easy as that:
fullscreen:
val picker = MaterialDatePicker.Builder.dateRangePicker().setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar_Fullscreen).build()
dialog:
val picker = MaterialDatePicker.Builder.dateRangePicker().setTheme(R.style.ThemeOverlay_MaterialComponents_MaterialCalendar).build()

While the posted answer totally work there seems to be no need to set the materialCalendarTheme globally - you can just set it to via the MaterialDatePicker.Builder and setTheme(int themeResId) method. Following an example how they do it in the Material Design Catalog App.
val datePicker = MaterialDatePicker.Builder.dateRangePicker().apply {
context?.resolveOrNull(R.attr.materialCalendarTheme)?.let {
setTheme(it)
}
setCalendarConstraints(getConstraints())
}.build()
// ...
resolveOrThrow helper method:
fun Context.resolveOrNull(#AttrRes attributeResId: Int): Int? {
val typedValue = TypedValue()
if (theme.resolveAttribute(attributeResId, typedValue, true)) {
return typedValue.data
}
return null
}
This way you DatePicker dialog won't be full screen but a regular dialog.

Related

Time picker customisation

Project has the design of time picker dialog.
the design as follows
then default dialog design is like below
I want the top section of this time picker dialog should be same as the expected design.
I have tried following xml code. nothing helped.
<TimePicker
android:id="#+id/timePicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numbersBackgroundColor="#ddd"
android:overScrollMode="never"
android:headerTimeTextAppearance="#drawable/bg_time"
android:headerAmPmTextAppearance="#color/yellow"
android:amPmBackgroundColor="#color/yellow"
android:headerBackground="#android:color/transparent"
/>
And I have added following code to set the title color to transparent. so that I can put my view on the top section.
android:headerTextColor = "#android:color/transparent"
but it says and threw the error
"Unknown Attribute android:headerTextColor"
. in the design part of the XML layout, it set the transparent color to title. but when I run the app it threw the error of
"Android resource linking failed".
Use Material TimePicker to achieve the following design
val picker = MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_12H)
.setHour(12)
.setMinute(10)
.setTitleText("Select Appointment time")
.build()
To show dialog
picker.show(supportFragmentManager, picker.toString())
Using theme attributes and styles in res/values/styles.xml to change color according to your need:
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="colorPrimary">#color/shrine_pink_100</item>
<item name="colorOnPrimary">#color/shrine_pink_900</item>
<item name="colorOnSurface">#color/shrine_pink_100</item>
<item name="chipStyle">#style/Widget.App.Chip</item>
</style>
You need to create a custom style in themes.xml. And then set that theme/style to your time picker in xml. This is example of a style:
<style name="MyTimePickerWidgetStyle" parent="#android:style/Widget.Material.TimePicker">
<item name="android:headerBackground">#color/stayGray</item>
<item name="android:numbersTextColor">#fff</item>
<item name="android:numbersInnerTextColor">#fff</item>
<item name="android:numbersSelectorColor">#color/stayGray</item>
<item name="android:amPmTextColor">#fff</item>
</style>
This is how you set style to time picker in xml.
<TimePicker
android:id="#+id/timePickerGoal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/MyTimePickerWidgetStyle"
style="#style/MyTimePickerWidgetStyle"/>

Is it possible to update the textfield in Material design date picker?

is it possible to add an outline and hide the mm/dd/yyyy text in material design date picker :
https://material.io/components/date-pickers#anatomy
I am trying to make it such that the outline of textfield should be customizable.
Any suggestions?
You can customize the style of the TextField using:
MaterialDatePicker.Builder.datePicker()
.setTheme(R.style.ThemeOverlay_App_DatePicker)
.build()
with:
<style name="ThemeOverlay.App.DatePicker" parent="#style/ThemeOverlay.MaterialComponents.MaterialCalendar">
<!-- Customize text field of the text input mode. -->
<item name="textInputStyle">#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
</style>

how to change the status bar color of datepicker?

I have a data picker:
val builder = MaterialDatePicker.Builder.dateRangePicker()
val picker = builder.build()
picker.show(childFragmentManager, picker.toString())
and it's status bar color black:
I want it to be transparent like in fragment which hosts this DataPicker:
how to do it?
After some in-depth research of the theming of the material date picker, I was able to figure it out:
In your activity theme you have to add
<item name="materialCalendarFullscreenTheme">#style/CustomMaterialCalendarFullscreenTheme</item>
And create the theme the following way
<style name="CustomMaterialCalendarFullscreenTheme" parent="ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen">
<item name="android:windowIsFloating">false</item>
</style>
You could add a custom status bar color by adding this to the CustomMaterialCalendarFullscreenTheme:
<item name="android:statusBarColor">#color/someCoolColor</item>
Note: If you are not interested in what caused the problem you could stop reading here!
The reason is that one of the ancestors of ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen has android:windowIsFloating set to true and if the 'floating' content is very big (as in our case, it is fullscreen) Android decides to change the status bar color to black.

Android Time Picker (change clock hand Color programmatically)

I have created a time Picker with below style. colorControlActivated will set the clock hand Color*(reference : http://www.zoftino.com/android-timepicker-example)*. But during run time is there a way to set this color programmatically.
Consider a scenario: If I select a time, less than current time then the clock hand color should change to RED color.
<style name="AlertDialogDatePicker" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="colorAccent">#color/white</item>
<item name="android:textColorPrimaryInverse">#color/black</item>
<item name="android:textColorSecondaryInverse">#color/red</item>
<item name="colorControlActivated">#color/blue</item>
Try this one.
MainActivity.class
TimePicker timePicker = new TimePicker(new ContextThemeWrapper(MainActivity.this, R.style.AlertDialogDatePicker));
DatePicker datePicker = new DatePicker(new ContextThemeWrapper(MainActivity.this, R.style.AlertDialogDatePicker));
I've found my own answer and it is quite simple. When instaciating the TimePicker and DatePicker send as parameter a new AlertDialogDatePicker with the custom style you want in order to change the style.

How to change textsize in datepicker?

The default textsize in datepicker is too big for my app. I've seen a way suggested to change it here, but fishing around for the textviews nested inside the datepicker class seems clunky and error prone.
Is there a better/cleaner way to do it?
Setting a theme to DatePicker layout and adding android:textSize to it works for me.
In your layout's xml add a DatePicker applying a theme as shown below -
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="#style/NumberPickerStyle"
android:datePickerMode="spinner"
android:calendarViewShown="false"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
and then define the NumberPickerStyle in styles.xml specifying android:textSize like this -
<style name="NumberPickerStyle">
<item name="android:textSize">#dimen/number_picker_text_size</item>
</style>
The easiest way to change the font size of datepicker/timepicker/numberpicker is customizing the theme.
In styles file, set the default font size in the following way.
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:textSize">22sp</item>
</style>
Sean's approach made some glitches in the UI of picker itself in case there're a number of pickers and I think it's not perfect to apply text size to all the components under the picker.
Below is what I've used and it works perfect without any UI glitches.
<style name="PickerTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:editTextStyle">#style/PickerEditText</item>
</style>
<style name="PickerEditText" parent="ThemeOverlay.AppCompat.Dark">
<item name="android:textSize">24sp</item>
</style>
Sean's code works. but it is changing font size for all the other components also(textViews, buttons, etc...) So Here is the solution.
Create different style for time picker and use it on time picker theme.
<style name="my_time_picker_style">
<item name="android:textSize">24sp</item>
</style>
and use it on your timepicker
android:theme="#style/my_time_picker_style"
Look at video, how I did https://youtu.be/JMJ2ujhk9c0
use below code:
ViewGroup childpicker = (ViewGroup)datePicker.findViewById(Resources.getSystem().getIdentifier("month", "id", "android"));
EditText mornthEt = (EditText)childpicker.getChildAt(1);// month widget
//change textsize and textcolor for mornthEt
mornthEt.setTextSize(30);
mornthEt.setTextColor(Color.GREEN);
use below code
DatePicker picker = (DatePicker)findViewById(R.id.dp_date);
ViewGroup childpicker
= (ViewGroup)
findViewById(Resources.getSystem().getIdentifier("month" /*rest is:
day, year*/, "id", "android"));
EditText textview = (EditText)
picker.findViewById(Resources.getSystem().getIdentifier("timepicker_input",
"id", "android"));
textview.setTextSize(30);
textview.setTextColor(Color.GREEN);

Categories

Resources