Layouts & Resources — Android Tutorials pt. 4
Hello again! On last post, we’ve created our first Activity, and got a basic understanding about Intents! Today, we’ll learn a bit about resources on Android and create a layout for our Activity.
This post is basically about the res folder, found in path app/src/main/res. This folder hosts all the project resources, basically everything that is not Java code. The project, until now, may have some folders, like an empty drawable, mipmap (with some ~strange~ variations) and values.
An Android project, in general, uses to have some others, that we’ll see in detail when necessary. Each folder contain a different kind of resource from our project. The drawable folder will contain anything ‘drawable’, like shapes, images and selectors. The mipmap folder keeps our app icon. The values folder contains general values, like integers, strings, colors, dimensions, styles, and so.
If you open any of the mipmap folders, you’ll note that we have the same app icon (with the same name), but with different sizes. This is because of the diversity (sometimes called fragmentation) of Android devices, with different configurations. A configuration is defined by both the device specs (like screen size and resolution) and preferences (like locale). The *dpi suffixes are about the screen density. The bigger is the device screen density, more pixels it have in an inch. Example: a device with a 4.7 inches screen, and a resolution of 480x800 pixels have a smaller density (hdpi) than a device with the same 4.7 screen, but with a resolution of 1080x1920 (xxhdpi). As Android supports a wide range of screen sizes and resolutions, we usually don’t use pixels for measuring, but density independent pixels. So, a button should have almost the same size in any screen resolution or size. To learn more about it, check the Android docs about it.
And maybe some of you are asking: how this magic is done? It’s not magic. When you puts a qualifier in a folder, the OS, when executing, checks the device configuration and uses the specific resource that matches its configuration. So, we don’t need to make a lot of checks and conditionals when coding. It’s relevant to say that we can have a lot of different qualifiers or even more than one qualifier in a folder. Soon we will see some interesting cases of this.
So, just to summarize, if the app is running in a xhdpi device and it needs the mipmap/ic_launcher resource, it will automatically get the mipmap-xhdpi/ic_launcher resource. If it don’t find a specific version that matches its configuration, it will use a generic version, from a folder without any suffix (or, in some cases, for images, it will try to scale an image from another folder).
Alright, as we got some basic understanding of resources, let’s create a new folder called layout inside the res folder. This folder, as the name suggests, will hold our layout files. Create a new file called activity_main.xml. You will note that most of the Android resources are actually XML files.
In this file, we will start with a container, the LinearLayout. A container specify the behavior of other visual components. The LinearLayout, our container in this layout, adds elements in a row, using the vertical or horizontal orientation. So, adding the LinearLayout, our activity_main.xml file looks like this:
You can note that we specified the orientation attribute, and the width and height attributes. For those dimensions, we can use a numeric value, or one of the constants: match_parent or wrap_content. match_parent indicates that the element will use the same value as its parent for the selected property. As LinearLayout is our first element in our hierarchy of view, it will hold its parent size (of some Android container that represents the screen). So, we have a LinearLayout that matches the screen size.
Now, let’s add two text inputs and a button to our layout.
The text inputs in Android are called EditTexts. Other than width and height, we will specify the id and the hint attribute for it. On Android, IDs are identifiers that allow us to reference the elements both in another places of XML, or in Java code. The @+id notation indicates that we are creating this id if it not exists. Always when you see an @ in Android XML files, it’s because is a resource reference (id is a resource too). In the hint attribute, we are referencing a string resource (that is present in the res/values/strings.xml file):
In the Button element, we have similar properties, but with the text property instead of hint.
With the file created and the layout added, let’s move back to our MainActivity and define this file as its layout. For this, let’s call the setContentView() method inside the onCreate(). This method receives and object of View type, or a reference of a layout resource. Note the R class. It is generated automatically on each build, and it’s a Java reference from all our resouces. As we already checked the Intent in last post, you can remove the log lines. The method should look like this:
Now, if you execute the app, it will show something like this:
For a better appearance and experience, we can centralize vertically the elements. To do this, we can add the gravity property to our container, with the value center_vertical. This property defines how the container children behaves when added. So, now we have:
And that’s it! In the next post, we will learn about binding the views on Java code and know about the callbacks! If you want to check the current code of our project, you can browse or download it from Github!
Stay tuned! :)