The libraries in the first category could of course handle this as they were full calendar apps, but we knew that only the libraries of the simple calendar view category would be feasible in integrating with our app. So, we concluded the optimal member experience could only be achieved by writing our own library.
But if we were going to write our own library, the next question was, how do we get the most use out of it? At that point, we realized we could help other developers avoid the exact issues we had faced by open sourcing our library!
We had a few core design goals in mind when developing the custom display logic. First was the rendering performance. Since our day view was going to have to display N events per day, we realized early on that support for view recycling would be critical. We kept the recycling logic simple by only recycling event views between days, so each individual day still requires N views to be created or reclaimed from other days. But our aim was to ensure that the swiping between days was smooth, and this sort of view recycling helped.
After implementing view recycling, we noticed the scrolling performance still wasn’t good enough. Luckily, we found an easy fix by adjusting the hour and half-hour dividers. Originally, each divider was its own view, but dividers are really just simple lines that can be rendered directly to the canvas. Switching over to direct rendering brought our scrolling performance up to the standard of smoothness we expected.
Another core design goal was internationalization. To support multiple languages, we made sure that all of the text we displayed used a generic formatter that didn’t assume the language was English. A hard issue to tackle here was how to lay out the views for RTL (right-to-left) languages. To prevent RTL mode from drastically increasing the complexity of our layout logic, we implemented a simple translation layer that processes all layout geometry in the day view. When RTL mode is detected, the horizontal coordinates of the child views are flipped and shifted by this translation layer.
Our implementations in the day view are different between iOS and Android. Even though the design goals were consistent, each platform posed a different set of questions we needed to answer.
On iOS, we had to choose between Swift and Objective-C for our programming language. We picked Objective-C for our programming language for the following reasons:
Another question on iOS was how we would format dates and times. Internally, we used the NSDate object to manipulate timestamps. To format the timestamps into localized text, we created a custom pipeline using NSLocale and NSCalendar objects. This allowed us to support over twenty different languages and locales.
Switching over to Android, the main question was around which SDK versions we would support. One positive aspect of creating a custom view is how isolated the logic can be from the rest of the app. Although we originally developed the day view internally within the LinkedIn Android app, we realized it could support a lower SDK version than the LinkedIn app does. Our app supports Android SDK version 21 and higher, but our library supports everything back to version 14.
Our day view library is now live on GitHub for Android and is coming soon for iOS. We’d obviously welcome any contributions or feature requests for either platform, but one engineering principal we’re following is “Keep your project scope well defined!” As mentioned previously, there are already some great open source projects that provide a full featured calendar experience. Our library’s purpose is to provide a reliable and robust calendar day view.
Having said that, if there are any use cases within the project’s scope that we haven’t thought of yet, we’d love to hear them. To contribute to the project or to request a feature/bug fix, please visit our GitHub page.