This app shows you what a monetary amount converts to from one currency to another using the Currency Layer API.
The project is designed with several paradigms:
- Modularization of components using Dagger to support app scalability
- MVVM: Strict separation of view, model and viewmodel data
- Reactive paradigms to minimize complexity and duplication
- View lifecycle aware data for performance (if the app had more activities/fragments)
- Discrete model repositories backed with Room Persistance Library for offline usage
- Material UI Design to look stylish
Select a source currency, destination currency, and input the currency amount. The list below will populate with the conversion rate between those currencies. In the action bar menu, you may clear the database at any time. Additionally, you may swipe down to refresh the data if it has grown stale.
Here is a high level overview of the project. It is organized and structured around the module components.
Dagger Component & Module Hierarchy
AppComponent
│
├───AppModule
│ └──AppContext─>──┐
└───NetworkModule │
└──Retrofit─>────┤
│
┌──────<────────<──────┘
│
CurrencyComponent
│
├──CurrencyAPIModule
│ └──CurrencyAPIClient─>───┐
│ │
└──CurrencyDataModule │
├──CurrencyRepository─>──┤
└──QuoteRepository─>─────┤
│
(Injects Into)
↓
CurrencyActivity
│
(Passes into)
↓
CurrencyViewModel
App Component - Contains all the modules core to the app
- App Module - Provides app context
- Network Module - Provides API agnostic Retrofit client
Currency Component - Contains all the modules required for Currency Conversion
- Currency API Module - Uses Network Module to provide a baked client with the currency API
- Currency Data Module - Uses App Module to provide both repositories
Thus, CurrencyActivity has all its required dependencies for its viewmodel
All the logic for data loading, currency conversion, and managing in-memory data happens in CurrencyViewModel. The viewmodel observes the repositories and transforms the raw data into processed data for the view to easily consume.
This is the data flow for how quotes are loaded. This does not include loading the currency list.
- App starts or user swipes down to refresh
- Viewmodel fetches data from the API if data is stale
- Retrofit kicks off network request
- Network call finishes, response mapped to POJO
- Viewmodel checks response object a) If there is an error, an appropriate error event is posted b) If no error was found, the data is passed to the repository
- Repository maps response to database entity & saves it
- Viewmodel is observing repository, when new data set is loaded it builds an adjusted list according to the set currencies/amount
- Activity is observing Viewmodel, when new data set is loaded it sets it in the adapter
- Adapter builds item views for the recyclcerview and displays on screen