I first wrote the NewsUp! App in 2017 to learn Android and haven’t touched it since then. After looking through the code, I realized that it’s definitely time (it really reeks of some bad architectural patterns 🙂) to update to a modern stack using the new shiny tools that the Android world has to offer. As such, I took some time to weigh my options to make this migration meaningful and a great learning experience. Of course, I’d be using Jetpack Compose, Dagger Hilt, Moshi and Flows as the pillars of the new app.
I was also intrigued in playing around with Airbnb's Maverick framework due to the premise it's built on top of the Jetpack library and Kotlin coroutines. In other words, the framwork helps make complex problems that typically arise in most apps such as threading, state synchronization, etc easier to deal with. Since I'm using Jetpack compose, the framework would primarily be used for business logic and data fetching while composables consumes the state emitted from Mavericks viewmodel (i.e MavericksViewModel)
Here's a google doc that notes some of the interesting issues I encountered and some of the design decisions that were made.
The Headlines screen makes a fetch to the ../top-headlines endpoint from NewsApi.org and with
this endpoint there is a set of categories that can be appended to the query to receive a liist of news articles based on the associated category.
Since there isn't a viewpager implementation for Jetpack compose, I instead opted for the Accompanist horizontal pager
that mimics a viewpager.
headlines_screen.mp4
The News Sources screen pings the ../sources endpoint from NewsData.io since it contained more news sources than
NewsApi.org and seemed more inclusive of different countries/languages. A user can select a single category to make the search more refined. Notice that the category items are composed of single selection chips that wrap to the next line using FlowRow. To pair with the category chips is a LazyColumn that shows cards of each news source with its name. Check out the entire [PR] (#9)
news_sources_screen.mp4
When a user clicks on one of the news sources in the main NewSources screen, they're presented with a details page of that news source with keywords
shown as outlined texts but most importantly its top articles from today as LazyColumn. Notice that as a user scrolls, the top bar is pinned to the top
of the screen along with the article's title, back navigation and search icon. This pinned top bar with a scrollable content section implementation is
also seen if you click on one the articles for that news source. This is all provided from Material 3's CenterAlignedTopAppBar where we simply just set the topBar
parameter in the main scaffold and implement some logic in the app state holder to ensure the top bar is shown on appropriate screens.
news_source_details_screen.mp4
The Search screen makes a fetch to the ../get-everything endpoint from NewsApi.org and
makes use of Maverick's Async sealed class to handle the Unitialized -> Loading -> Success/Failure states
without any fancy operators to be done on the stateflow being collected in the Search screen. In the Sarch screen composable, all that has to be done
is a mapping of what to do for the different states in typical MVI scenarios. Here's the PR
search_view_screen.mp4
Previously implemented using WebView to show news articles and sources but noticed how it wasn't smooth and would regularly not load correctly. As such, I migrated web content logic to using Chrome Tabs. Here's the PR
webview_screen.mp4
For every endpoint that we could hit, there's a language and/or country query parameter that can be assigned to meet the user's preference. As such,
it makes sense for the user to set these values in a single place and be used in queries afterwards to meet a user's language preference or country they're
intrigued in. Jetpack's Datastore library is the recommended preferences manager
to use in such cases. Check out the PR
preferences_screen.mp4
- Airbnb Maverick Framework
- Jetpack Compose
- Datastore
- Retrofit
- Material Design 3
- Moshi
- Dagger Hilt