In Android we have to deal with both big screen and small screens, tablets, watches, TVs and many other devices. In our case, we had a device with a 3.2″ display and other one with 5″ display. And on both of them we show a DatePicker dialog to choose a date. And guess what? Especially for the current month of October, there was a small difference. Can you guess it in the screenshot below?
One day is missing
I guess you already saw the difference. 31st of October is missing. If you don’t remember that this month is 31 days, you could have actually skipped it at all. The reason why we don’t see the 31st on the left side is because the DatePicker and dialogs overall are limited in size.
The issue
Dialogs and DialogFragments are limited in height. They usually do not take up all the available space in terms of height and width. They have some paddings and also some distance from the top and bottom to make them better looking. And in the old times, up until now, there is a lot of code in Android XML that uses the android:layout_weight property as you can see here. It can be problematic in some cases where you want certain content to be visible on the screen.
With the above case, it was really hard for me to understand why is CalendarView not scrollable and where the issue is. I tried reducing the size of the dates, the size of the title and the issue was kinda fixed but I couldn’t get a decent looking 31st on the screen. That’s why I decided to move to using a custom layout + AlertDialog rather than fighting this DatePickerFragment. And here is how it worked.
The solution
The solution was to try to stretch the AlertDialog height as much as possible. As you can see, there is a lot of space at the top and bottom of the dialog that can be used. And I started looking into a solution.
Using a custom view
I decided to use a custom layout with an alert dialog. Now that I wanted to stretch it manually, it just didn’t make sense to keep the DatePickerDialogFragment. And using an AlertDialog inside a DialogFragment is very very easy.
The custom view would contain:
The CalendarView – it has a title that matches the one from the DatePickerDialog
The buttons – Cancel and OK which are simple TextViews and I could style them by using the style=”@style/Widget.AppCompat.Button.ButtonBar.AlertDialog”. Job done.
Stretching the dialog in onLayoutChanged
Adding a listener when layout changes for the dialog is quite simple. And there, we can make sure that our dialog has MATCH_PARENT, MATCH_PARENT in terms of width and height. Something like this:
Make sure to stretch the dialog only if space is not enough
I didn’t need to stretch the dialog for devices that are big and have enough screen space. That’s why I needed to detect whether a device has enough space or not. And what a bigger indicator than the CalendarView itself. If it matched or is higher than the AlertDialog height, this means the buttons are not visible and I need to make the dialog width and height – MATCH_PARENT. Otherwise, keep them as they are.
The result
Show me the code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters