Building an Android app — Part 3. Welcome to my series on building an…
By: Rakesh K
Tags: Android App Development

Activity

So far, we spoke about the UI in terms of screens and pages. In Android, the fundamental concept of a screen is an `Activity`. Why is it called an ‘Activity’ and not ‘Screen’ or ‘Page’? If we think about it, we usually do some sort of activity in any screen or there could be some activity that the application does for us to display content on the screen. And so, ‘Activity’ forms the basic unit of UI in Android. More details about Activity can be found here. As I listed earlier, I have multiple screens in my app and hence I have multiple `Activity` objects — one for each screen.

Now, out of all the activities that an app can have, we need to designate one as the ‘main’ activity or ‘Launcher’ activity. This is the Activity that gets launched during the app startup and is shown to the user and hence the name. Every time a new Activity is added to the app, an entry is made in the AndroidManifest.xml file. Among other things, the manifest file contains permissions needed by our app, activities used in the app, etc. By convention, when a new project is created in Android Studio, the main activity is created automatically for us and it’s called ‘MainActivity’ and it’s designated as `android.intent.category.LAUNCHER` in the manifest file.

View and ViewGroup

After we are given an Activity(either during project setup or added manually), we need to start adding the actual elements that the user interacts with to this activity. In Android world, these elements are called as ‘View’ objects. Most of the UI elements which are used to construct the UI are derived from the View class. Examples of such elements include TextView , EditView , RecyclerView etc. We will look into some of these in a short while.

In addition to View objects, Android also has ViewGroup objects, which are containers for other View objects. A most common example is the different layouts that can be used while constructing the UI. A layout is basically how the different elements are arranged on the screen and Android provides us with many pre-defined layouts — LinearLayout , RelativeLayout , ConstraintLayout etc. Can we construct the UI without using any particular layout? Yes. But then, the UI would be very brittle and it wouldn’t adapt to any configuration changes(e.g. screen dimensions, rotations, etc.)

Let’s build

Alright, we now know enough about the basics of the UI in Android to actually start building one. As a beginner, it’s always best to start with the option of ‘Empty Activity’ when creating a new Android Studio project. This keeps the scaffolding to the minimum and makes it easy for us to build the UI as per our needs without worrying much about the extra code generated with any other option. Having said that, these are the 2 files that are important to us right now — MainActivity.kt and activity_main.xml . In Android, we can build the UI in two ways — declaratively(using XML files) or programmatically (using Java or Kotlin files). Typically, it’s more convenient to build the UI using the XML files since it gives an intuition of how the elements are composed among each other without writing code about instantiating them, etc.

In the screen that I want as my home page, I want to display the following elements — an App Bar(also called a tool bar), a list view(to display the shopping lists) and a button to create a new list. Here’s how the XML file looks like with these elements:

Let’s go through the above file in detail — I have a layout RelativeLayout in which I added an AppBarLayout , a RecyclerView and a FloatingActionButton . In a RelativeLayout , the UI elements are placed in relation to each other. What this means is that we don’t have to specify the exact coordinates of the element(which is actually a bad idea) that are used by the OS to draw them on the screen. Instead, we define the position of the elements inside the RelativeLayout using attributes such as layout_below , layout_above , layout_alignParentStart , etc. Each of these attributes is pretty self explanatory and it’s more fun to try them out to see how the positioning of the elements change accordingly.

Next up is the AppBarLayout — this layout is exclusively for positioning the tool bar in our app. Here’s a gotcha we need to be careful when setting up the project: we need to select a theme which does not have an action bar built in. What does this mean? If we look at the other files that have been created for us while creating a new project, we will find themes.xml or styles.xml . Think of this file as a CSS equivalent in the web world. This file is where we define the styling of the elements and also provide the theme details that can be applied across the app. Now, by default, the theme provided by Android Studio for us is Theme.MaterialComponents.DayNight.DarkActionBar . As the name implies, this applies a dark theme for our app(yay!). But what this also does is provide our app with a default action bar which we didn’t ask for explicitly! If we now add an action bar explicitly in our app, we will end up with having 2 action bars, which is ugly. To avoid this, it’s best to change the default theme with the one that does not provide an action bar. One such example is Theme.MaterialComponents.Light.NoActionBar .

Now that we don’t have the default action bar, we can add one using MaterialToolbar element within AppBarLayout element. We can define some attributes such as the width, height, title text, title text color etc in the tool bar element. Here’s some more important stuff — we’ll most often see the words match_parent and wrap_content as values defined for the attributes layout_width and layout_height . The value match_parent sets the width/height of the element to match that of its parent; wheres the value wrap_content limits the width/height of the element to the maximum width/height of its content or child elements. So for the elements that span the entire screen width or height, we would usually define the values as match_parent . But we need to be careful when we are designing the list view elements — setting the height of each element to match_parent will fill up the entire screen with just one list element, causing all sorts of frustration and wastage of time.

Next up is the list view. In Android, there are two common ways of defining lists — ListView or RecyclerView . The intuition here would be to choose ListView to build a list, but the advice from Android team is to use RecyclerView . Why? As the name suggests, a RecyclerView recycles its elements once they go out of visibility of the user(when we scroll up or down). This is a really clever way to save memory since the OS can now reuse the same elements to paint a different content! But — is there a penalty to re-setting the content every time the elements go in and out of view? Well, there is some penalty, but nothing that can bring down the app to its knees. TLDR; use a RecyclerView to build a list.

Finally, we have the FloatingActionButton the one that we see very often these days — a circular button with a single character at the bottom right corner of the screen. To set the ‘+’ icon to the button here, I had to import the icon pack from here and then import them using the ‘Resource Manager’ tool in Android Studio. Once imported, the icon is added to the ‘drawables’ directory, which holds anything that can be ‘drawn’ on the screen such as images, icons, etc. I then import the icon by using @drawable prefix to the icon name, without the file extension.

Another key point while building any UI in Android — always provide an ‘id’ to every element that’s added. We can see this in the above code where the id is defined as @+id/app_bar_layout and so on. By prepending the id string with +id , we are asking Android to register the id as a new element in the global id registry. We will see how we can use these ids in the code in the next part.

Build, Run and Magic

Finally, with this layout, here’s how the screen looks like:

That’s it, we’ve built the first screen! Another great tip to save a ‘lot’ of time during development — use a real phone to launch and test your applications instead of the emulator as much as you can. There’s no startup time in the case of a real device and hence you can launch the app real fast. Plus you can show off the cool new app on your phone!