How I Built a Simple Currency Converter App — Using Recommended Android Pattern and Architecture

Inuwa Ibrahim
Jan 5 · 7 min read
Image for post
Image for post

Hello, In this article, I will show you how to build a very simple currency converter app that lets you convert figures from one currency to another.

In this app, I carefully followed the clean architectural pattern — as recommended by the Android team.

This app uses —

  • Kotlin
  • MVVM (Model View ViewModel Pattern)
  • Hilt (For Dependency Injection)
  • An API to get currency rate and conversion (https://currency.getgeoapi.com/) (You can use any!)
  • Retrofit (For making API calls)
  • Flow
  • LiveData
  • Coroutines (For simplifying Asynchronous operations)
  • View Binding (For interacting with views)
  • Some other libraries

AND…NO — I didn't use Android Navigation Component — Its a single activity app 👽)

This is how the final app will look like

Image for post
Image for post

And this is a video showing how the app works

OKAY…LETS START CODING!!

STAGES

  • Setting up Android studio
  • Adding all the necessary dependencies
  • Setting up Splash Screen
  • Setting up required resources
  • Building View/Layout
  • Create Utility And Helper Classes
  • Setting up Retrofit
  • Setting up Hilt (Dependency Injection)
  • Setting up Model
  • Set up Repository and View Model
  • Setting Up Activity

That was one hell of a list, I know! lets take them one by one and we’ll be done in no time. I promise 😐

SETTING UP ANDROID STUDIO

ADDING ALL THE NECESSARY DEPENDENCIES

Before adding our dependencies, lets refractor our project structure by creating 6 packages. Right click on project package — New Package. Name them — di, helper, model, network, view and viewmodel. After that, move MainActivity to the view package you just created

Your project should now look like this

Image for post
Image for post

Now open manifest — AndroidManifest.xml file. Add the following permissions for accessing network because we need to be connected to the internet to make API calls.

<uses-permission android:name="android.permission.INTERNET" />
<
uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<
uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Okay lets add our dependecies.

  • Open build.grade(app)
  • Add the dependencies below (I added a comment to explain what each dependency does)
  • Note — There are some dependencies I added which we may not use for this project (E.g Room, Glide). We may need them later on when updating the codebase or adding new feature such as caching etc

SETTING UP SPLASH SCREEN

A splash screen usually appears while an app is launching/loading.

Instead of showing a blank screen, we will show our app logo.

  • Copy any image you want to use as the splash screen logo and paste it in the drawable directory.
  • Make sure you use a png image with a size of around 114dp X 114dp. I’d recommend you use Batch Drawable Import for displaying appropriate images for different resolution. Search for that plugin and read on how to use it.
  • Now, create a new drawable resource file in the drawable directory — name it splash_screen.xml
  • Input the code below
  • Navigate to values directory and open styles.xml file, we will add our Splash Screen Theme here
  • We will create our font directory later, so ignore the error
  • In your Manifest.xml add the attribute android:theme=”@style/splashScreenTheme” to your MainActivity
<activity
android:name=".view.MainActivity"
android:theme="@style/splashScreenTheme">
<
intent-filter>
<
action android:name="android.intent.action.MAIN" />
<
category android:name="android.intent.category.LAUNCHER" />
</
intent-filter>
</
activity>
  • Finally, in your view/MainActivity class. Inside onCreate method Before super.onCreate method, set the activity theme to your app theme. Like this:-
override fun onCreate(savedInstanceState: Bundle?) {

//here
setTheme(R.style.AppTheme_NoActionBar);

super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}

SETTING UP REQUIRED RESOURCES

We will now set up resources such as strings, colors and font for our app.

  • Open colors.xml
  • Paste this code there
  • Open strings.xml and modify
  • Right click on res directory, create a new Android Resource Directory, name — font, set Resource type — font click Ok.
  • Now go to https://fonts.google.com/ and download Convergence font, extract and paste the font in that directory — The directory should be like this res/font/convergence.ttf

Yeaah!! 👏

BUILDING VIEW/LAYOUT

  • Open layout/activity_main.xml
  • Paste the code below
  • Create a new drawable, named — edit_text_input_with_border (Used for styling the editText field)
  • Paste the following code
  • Create another drawable — named — edit_text_input_with_border_2
  • Paste the following code
  • Finally, create the last drawable — named btn_main_round (For styling the convertbutton)
  • Paste the following code

Our layout now looking set 😺

CREATE UTILITY AND HELPER CLASSES

These classes will help us handle network state, hide the keyboard in our activity, make status bar transparent and handle single live event, which is always aware of a view LifeCycle.

  • Under helper package Create a new Object called Utiltity.kt
  • Put the following code there
  • Create a new class EndPoints.kt under the same helper package
class EndPoints {

companion object {

//Base URL
const val BASE_URL = "https://api.getgeoapi.com/api/v2/currency/"

//API KEY - Go to geo currency converter website, obtain an API key and paste it between " "

const val API_KEY = " "

//COVERT URL
const val CONVERT_URL = "convert"

}
  • In order to make this tutorial not extremely lengthy, I will urge you to take a look at the repo for this project and check out the other classes under the helper package

https://github.com/ibrajix/DirectCurrencyConverter

SETTING UP RETROFIT

Retrofit makes it very easy to consume RESTful web services. Retrofit automatically serializes the JSON response using a POJO (Plain Old Java Object) which we will define in our data structure.

  • Under the network package, create an interface named — ApiService.kt
  • ApiService This interface contains all the possible HTTP operations needed to be carried out, for our app we are simply making a GET request to our API with several parameters.
  • Under the same package, create a new class called ApiDataSource.kt
  • This class exposes the ApiService interface so we can use it in our repository, which we will create later on.
  • Create a class called — BaseDataSource
  • This class helps handle state of the request — either successful, failed or loading so we can perform appropriate actions or show appropriate error message.

SETTING UP HILT FOR DEPENDENCY INJECTION

  • We have already added the dependency for hilt in build.gradle(app)
  • Navigate to build.gradle(project)
  • Inside the dependency block, add hilt class path, it should look like this
dependencies {
classpath "com.android.tools.build:gradle:4.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

//hilt for di
ext.hilt_version = '2.28-alpha'
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
  • Create a new kotlin class inside the di package — MyApplication.kt
  • We will annotate this class with @HiltAndroidApp — This will help us generate all the required hilt codes including a base class that serves as the application-level dependency container.
  • Create another kotlin class under the same package, name it — AppModule.kt
  • This class is used to perform injection to types such as interfaces and classes from external libraries which we do not own. We will tell hilt how to provide instances of certain types.
  • The code looks like this
  • Update your manifest.xml. Add android:name=”.di.MyApplication” to application block like this
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
//add this line
android:name=".di.MyApplication"

SETTING UP MODEL

let us create a data class for the Response gotten from the server as POJO.

  • Create 2 new classes under model package called ApiResponse and Rates — Note you can automatically model your Json to kotlin data class using the Kotlin Data Class from Json Plugin
  • For ApiResponse, this is how the code looks
  • For Rates, this is how the code looks like.Yours may be different depending on the type of Json data gotten from your API

SETTING UP REPOSITORY AND VIEWMODEL

  • In your viewmodel package , create 2 new classes called MainRepo and MainViewModel
  • MainRepo — This class interacts with our ApiDataSource which makes the network request. The data obtained from the request is emitted and returned as a flow which can then be collected in our viewModel which is ultimately observed in the View.
  • MainViewModel — This class interacts with the repository by collecting the data obtained from the request which can then be returned as Live Data for the MainActivity View.

SETTING UP ACTIVITY

Finally, let us set up our activity, all we have to do is

  • Initialize our view binding class and get a reference of all views in our layout
  • Set up the logic for handling click events for the spinner — Country list item
  • After inputting a value and hitting convert — Interact with the view model, observe the data and get the state of the request
  • Depending on the state of the request — Perform necessary actions.

Here is the MainActivity, all the codes, methods were properly documented and explained.

We have come to the end of the tutorial, I hope you’ve learnt a thing or two.

Here is a link to the full source code for this project —

https://github.com/ibrajix/DirectCurrencyConverter

Subsequently, I may add other features to this project. Features such as Caching, Adding countries flag, Implementing Search Feature etc.

Let me know what you think.

Thanks!

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store