Lesson Weekend

Now that we successfully have our app up and running in the emulator, let’s get to work! First we are going to make a basic welcome page with a button that will eventually link to a page with a list of restaurants.

While in the Android project view, navigate to res/layout/activity_main.xml. The res folder contains all of the static resources that comprise our app. This folder will house all of our images, layout files, launcher icon, and string, color, and style values. We will learn about all of these resources over time.

The activity_main.xml file is where we are going to style what the user sees and interacts with when they are viewing the welcome page of our app. As the filename specifies, layouts in Android are written in eXtensible Markup Language (XML) - that means no more CSS for us!

Reverting to Relative Layout

If we open activity_main.xml, we can see a sort of visual editor depicting a layout similar to the one we saw when launching our emulator. It looks something like this:

constraint-layout-editor

This is a Constraint layout, in a special visual Constraint layout editor. However, as we discussed in the last lesson, we're going to practice working with Relative layouts first before exploring Constraint layouts on Wednesday night. So, we'll need to revert this default Constraint layout back into its Relative cousin.

Do you recall how to do this? We'll follow the same steps introduced in the previous lesson:

  1. First, we'll delete this automatically-created activity_main.xml file from the res/layout directory by right-clicking on its file and selecting Delete.... A pop-up alert will ask you to confirm. Select OK. A second pop-up will alert you that this layout is being used in other parts of the app. Select Delete anyway. (Since we're going to immediately create a new layout to replace the one we're deleting, this is okay.)

  2. Then, we'll create a new layout file by right-clicking on the res/layout directory and selecting New > Layout resource file.

  3. A New Resource File pop-up with several fields should appear. In the File name field we'll insert the exact same name as the file we just deleted: activity_main.xml.

  4. In the Root element field of this same pop-up, make sure to replace LinearLayout with RelativeLayout. The remaining two fields can remain the same. Click OK. This will create a new layout for us. However, Android Studio will likely default to the visual editor we saw our Constraint Layout in earlier.

  5. To edit our layout's XML directly, we'll need to navigate out of the visual editor and into the XML editor. Near the bottom-left of the screen you should see two tabs reading Design and Text (see image below). Select the Text tab to toggle into the XML editor.

editor-tab-options

Make sure to go back and revisit the Creating Relative Layouts lesson if any of this feels unclear.

Altering the activity_main Layout

After switching to the Text editor of our newly-created Relative Layout, we should see something like this:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

</RelativeLayout>

Let's add a "Hello World" message, like our default-created Constraint layout previously had. We can do so by adding the following XML:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

At any point, we can also toggle back to the Design tab to preview what our layout XML looks like.

Adding and Altering Views

Let’s now change the existing "Hello World!" text and add a button. Each of these elements is what we will refer to in Android as a view. As we covered previously, a view is anything on the screen that we can see and/or interact with such as TextViews, Buttons, ImageViews, and so on.

To change the text, double click the TextView. We’ll change it to the name of our app, "MyRestaurants", and then reposition it so that it is centered horizontally. Let’s take a look at the resulting XML by switching to the text view. To switch to the text view, select the text tab at the bottom of the Palette. It should look like the following:

...
<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MyRestaurants"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="35dp" />
...

As you can see, the layout_marginTop property was automatically set to a value of 35dp when we repositioned the TextView. dp stands for density independent pixel and it is the unit of measurement we will use when specifying the size of our views in Android. Because Android devices have a variety of different screen resolutions, using pixels would result in views that would appear very small on the higher density devices and much larger on lower density devices. Using dps helps our apps to look consistent across devices.

Adding Views

Next, let’s drag and drop a Button view from the Palette menu into our layout. We’ll place it at the bottom center of the layout. Double click and change the text to "Find restaurants". The XML should now look like:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.epicodus.myrestaurants.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MyRestaurants"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="35dp"
        android:id="@+id/textView" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Find Restaurants"
        android:id="@+id/button"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

Adding Colors

Our welcome page doesn’t look all that great yet. Let’s go ahead and add some basic styles such as colors and a background image. Feel free to use any colors/images that you like. If you need help deciding on a color scheme, try this Material Design Color Palette site.

colors.xml Resource

Now that we have decided on a color scheme, let's go ahead and copy and paste the colors into our colors.xml file located in the res/values folder. It's generally considered a best practice in Android to not hardcode strings and color values into your user interface, but rather to consolidate them into their corresponding files inside of the res/values folder. Read more about Android resources here: Understanding App Resources.

Copying our colors into this colors.xml file will allow us to reference our colors all throughout our app by their "nicknames" instead of the more complex hex codes. Your colors file should now look like this:

res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#FF5722</color>
    <color name="colorPrimaryDark">#E64A19</color>
    <color name="colorPrimaryLight">#FFCCBC</color>
    <color name="colorTextIcons">#FFFFFF</color>
    <color name="colorAccent">#009688</color>
    <color name="colorPrimaryText">#212121</color>
    <color name="colorSecondaryText">#727272</color>
    <color name="colorDivider">#B6B6B6</color>
</resources>

Applying Colors

Now let's apply our colors to style our welcome page. With the "MyRestaurants" text selected, find the textColor property and then click on the three little dots to open the Resources file. In the color tab, we can choose from one of the many preset color values, specify a color using hexadecimal or RGB values, or scroll down to find the values we added to our colors.xml file. Let's select one of the colors we just added to our colors.xml file. I will use the colorTextIcons value which is simply white. The XML should now look like this with a link to our @colors file:

activity_main.xml
<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MyRestaurants"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="35dp"
        android:textColor="@color/colorTextIcons" />

Our background is currently white, so let's change it’s color for now so we can see what we are working on. Select the RelativeLayout from the ComponentTree, select the background property and type #000000. Our background should now be black.

Altering Font and Other Styles

Back to our "MyRestaurants" text, let’s make the font bigger so that it is easier to read. Select the textSize property and give it a value of 40sp. When specifying the size of text in Android, you should always use sp. sp stands for scale-independent pixel and it helps text to look the same across different screen sizes and different pixel densities. It is also affected by the font size preferences in the user’s settings. Let’s also make our text bold by checking the bold checkbox from the textStyle property dropdown.

Back in the design view, let’s add some styles to our button. With the button selected, click on layout:width option on the top left of the design view and change it to expand the width of the button to match the width of the parent. This icon looks like a square with two arrows inside pointing at the the center to a dotted vertical line.

Let’s also change the background color of the Button and change the font color of the text inside. Here is the resulting XML.

activity_main.xml
<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Find Restaurants"
        android:id="@+id/button"
        android:background="@color/colorAccent"
        android:textColor="@color/colorTextIcons"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"/>

While we are in the Text view of our layout, let’s also give our button an id. ids are important because they give us a way to refer to these views within our code. Let’s give our button an id of ‘findRestaurantsButton’ by changing the existing line android:id="@+id/button" ... to instead readandroid:id="@+id/findRestaurantsButton"`.

Adding Images

Last, let's use an image as a background for our welcome page layout. For free images, check out unsplash.

All images for an Android project are stored in the res/drawable folder.

Unfortunately, Android Studio does not let you drag and drop images directly into the drawable folder. Instead, Right click on the drawable folder and select Reveal in Finder to reveal the folder and drag and drop your images that way.

Next, let's add an ImageView to our layout and set the source property. Double click on the ImageView, click on the three little dots, navigate to the drawable folder under the Project tab and select the name of your image.

We want the image to fill the background so let’s change its scaleType property to centerCrop and the layout_height property to fill_parent. Uh oh, our image is covering our text! To fix that, open the XML view and copy and paste the ImageView XML so that it is above your first TextView. Let's also delete all of the padding properties from our RelativeLayout.

Now we are done with our activity_main layout. The resulting XML should look like this:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.epicodus.myrestaurants.MainActivity"
    android:background="#000000">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/imageView"
        android:src="@drawable/background"
        android:scaleType="centerCrop" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MyRestaurants"
        android:layout_marginTop="35dp"
        android:id="@+id/textView"
        android:textColor="@color/colorTextIcons"
        android:textSize="40sp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:textStyle="bold" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Find Restaurants"
        android:id="@+id/findRestaurantsButton"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@color/colorAccent"
        android:textColor="@color/colorTextIcons" />

</RelativeLayout>

Warning: Make sure your image file sizes aren’t too big. Excessively large images will cause the following error when attempting to run your app: java.lang.OutOfMemoryError. Resize your images to 1000pixels x 1000pixels or less to solve this issue.


Example GitHub Repo for MyRestaurants

Terminology


  • Extensible Markup Language (XML): The markup language used for formatting text in Android layouts.

  • View: In Android, anything that we can see or interact with on the screen.

  • dp: Density-independent pixel; Unit of measurement used to specify the size of views in Android to accommodate a variety of screens without a change in quality of appearance.

  • sp: Scale-independent pixel; A text size that helps text look the same across different screen sizes and different pixel densities. Like dp, but adjusted for both the screen density and user's preference.

Tips


  • The res folder contains all of the static resources that comprise an app.

  • All images for an Android project are stored in the res/drawable folder.

  • Make sure your image file sizes aren’t too big. Excessively large images will cause the following error when attempting to run your app: java.lang.OutOfMemoryError. Resize your images to 1000pixels x 1000pixels or less to solve this issue.

  • It's considered a best practice to not hardcode strings and color values into your user interface, but rather to consolidate them into their corresponding files inside of the res/values folder.

Examples


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.epicodus.myrestaurants.MainActivity"
    android:background="#000000">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/imageView"
        android:src="@drawable/background"
        android:scaleType="centerCrop" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MyRestaurants"
        android:layout_marginTop="35dp"
        android:id="@+id/textView"
        android:textColor="@color/colorTextIcons"
        android:textSize="40sp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:textStyle="bold" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Find Restaurants"
        android:id="@+id/findRestaurantsButton"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@color/colorAccent"
        android:textColor="@color/colorTextIcons" />

</RelativeLayout>

Additional Resources