September 15, 2016 · android zero-to-hero

Zero to Hero - Android App - Part 1 - Views

App development is never a straight-forward task. In fact, apps are built from many components that handle specific needs. It's up to you, the app developer, to determine which components you need, how they should be implemented, and how they should interface with the rest of the app. The most common component is called a View.

Android Views

Look around. What do you see? Sure, the specifics of what you and I see are different, but they both represent the same concept. We both see things that have some visual representation and are usually something we can interact with. In Android, views represent the same thing - They're essentially just the part of the app a user can see and interact with.

If you've never built an application before, Android or other, you might be a bit confused. Well, there's more to Android Apps than just the views! In fact, there's a lot going on behind the scenes of your views, but this is all logic that the developer — you — need to worry about and users will never know about. If you've never built an app before, you might not realize that there's so much that goes on behind the scenes. Now that we've covered the importance of views, let's start a new application and make our view!

A New Android Application

If you haven't already, launch Android Studio. If you've played around with Android Studio since the last post and need to get back to the launch screen, you can use the top-most menu to close your current project. Next, click Start a new Android Studio Project.

You'll be asked to fill out a few fields for the next part of this tutorial. These aren't super complicated so I'll go through them quickly:

Now, click "Next". In this next view, we're just going to check the box for Phone and Tablet and set the Minimum SDK to Android 5.0 (Lollipop). This is where you would add support for other types of devices, like watches or Android TV, but we'll skip that for now. You can always add support later, too. Go ahead and click "Next" once more.

In the next screen, you'll be presented with the option to "Add an Activity to Mobile". We'll get into Activities in our next tutorial, but for now, click "Empty Activity" and then click "Next".

Finally, we'll have one more set of prompts. For activity name, type: AddTaskActivity. Make sure Generate Layout File is checked. The Layout name should be auto-set to activity_add_task. Now, click finish!

Technically, you've just built your first Android app, even though doesn't really do anything - yet. We're going to change that.

A Few Tips Before We Start Coding

Android Studio can be overwhelming, especially if you've never used an IDE (Integrated Development Environment) before. There are a lot of buttons and a massive list of files. I'm going to do my best to give you exact instructions, but here are a few tips:

Our First Android View

Views in Android are written in XML. If you have little or no experience with XML, fret not! It's actually really basic to use! Although I won't go over the intricacies in this post, there are a few things worth mentioning:

In the right-most pane, you should see some Java Code. At the top of that pane, you should see some tabs opened. Click the tab labeled activity_add_task.xml. You should see something like this:

<?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.bradcypert.turnip.AddTaskActivity">

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

If you don't see that, but instead see a picture of an Android Phone that says "Hello World" click the "Text" tab at the bottom of that pane.

Go ahead and delete it all. We're going to build our view from scratch and I'll talk about each element as we add them. The first thing we want to add is the <xml> tag.

<?xml version="1.0" encoding="utf-8"?>  

This specifics that the version of XML used to parse this document is version 1.0, and it's encoded in UTF-8. Don't worry too much about fully understanding what that means, just know that each XML document that we'll add needs this line.

Next, we have to define the base layout that we want for our view. We're going to add a LinearLayout. A LinearLayout tells our Android Application that the direct children of this view should be rendered in a vertical line. Add this code:

<LinearLayout 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.bradcypert.turnip.AddTodoActivity"
    android:orientation="vertical">

There's a lot happening in this element. Let's talk about each attribute one at a time.

Phew. A mouthful! Next, we're going to add something called an EditText. An EditText is simply a way for users to input text. We'll use this as a means to let users name the task that they want to complete.

<EditText  
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/addNewTaskName"
        android:textSize="26sp" />

You might notice a few different things here. For example, we're using wrap_content instead of match_parent for the height. That tells the element that it should only be as tall as it needs to be for all of it's content to be visible. We're also adding an android:id. An ID provides a way to uniquely reference this element from the rest of our application. This will be very relevant later once we need to get the text that the user input into this element. android:textSize determines how big the input should be. Text Size is in a unique unit as well, called SP. Remember this: Text is SP. Everything else is DP. If you're XML-savvy, you'll also notice that this element is self-closing, meaning it doesn't need a closing tag. We didn't add a closing tag for the LinearLayout either, but we will need to in the near future.

Next, we're going to add some space in between our views. There's actually several ways to do this, but one of the most obvious ones is creating a new Space element. So let's go ahead and do that.

<Space  
    android:layout_width="20dp"
    android:layout_height="20dp"/>

This tells our Application that I want a space of 20DP tall to be in between the elements we just added and the elements that we're about to add. Very simple!

Next, we want to add something called a switch. Android switches come with a few defaults setup for the text that it's displayed, and while that's something we can overwrite, we're just going to choose to leave the text off of the switch and create a text element instead. Basically, we want these to be side by side so they look as if they belong together. To do that, we'll leverage a tool that we've already used, called a LinearLayout. Remember how we can define the android:orientation for a linear layout? That's exactly what we need.

<LinearLayout  
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_gravity="center_vertical">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Want a reminder?"
            android:id="@+id/textView"
            android:layout_weight="0.60"
            android:textSize="24sp"
            android:layout_gravity="center" />

        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/reminderSwitch"
            android:checked="false"
            android:showText="false"
            android:layout_gravity="bottom" />
    </LinearLayout>

I won't go over all of these properties, as you should be able to figure most of them out by now, but I'll highlight a few things:

We've covered almost all of the elements and their property, so this next block of XML to add will be the biggest block yet, however, we only need to talk about Buttons and Button types. Here we go!

   <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="How frequently do you need to do this?"
        android:id="@+id/textView2"
        android:textSize="18sp"
        android:layout_marginBottom="20dp"
        android:textAlignment="center" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal">

        <ToggleButton
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Daily"
            android:textOff="Daily"
            android:textOn="Daily"
            android:background="@drawable/select_button"
            android:textColor="@color/select_button_color"
            android:id="@+id/toggleDaily"
            android:elevation="2dp" />

        <ToggleButton
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Weekly"
            android:textOff="Weekly"
            android:textOn="Weekly"
            android:background="@drawable/select_button"
            android:textColor="@color/select_button_color"
            android:id="@+id/toggleWeekly"
            android:elevation="2dp" />

        <ToggleButton
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Monthly"
            android:textOff="Monthly"
            android:textOn="Monthly"
            android:background="@drawable/select_button"
            android:textColor="@color/select_button_color"
            android:id="@+id/toggleMonthly"
            android:elevation="2dp" />
    </LinearLayout>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Create Task"
        android:id="@+id/createButton"
        android:background="@color/colorAccent"
        android:textColor="@color/abc_primary_text_material_dark"
        android:layout_marginTop="15dp"
        android:minHeight="50dp" />

</LinearLayout>  

First thing's first. Remember how I said we'd have to close out that LinearLayout earlier when I mentioned how XML-savvy you were? Well, we close that out here. We add another TextView to present the user with some more text, and we add a LinearLayout to put some ToggleButtons next to each other. Lastly, we create a Button.

ToggleButtons

ToggleButtons are interesting. A ToggleButton is simply a button that can be turned "on" or "off", which sounds an awful lot like a switch (like we used above). We only want one ToggleButton to be "on" at a time so we're going to define custom behavior. With this behavior the user can press a button, and if the user switches to another ToggleButton, it will untoggle the current one. This will allow them to only select one timeframe at a time: daily, monthly, or weekly. android:textOff and android:textOn allows you to set the text for when the button isn't toggled and is toggled, respectively. For us, we want them to show the same text regardless of whether they're on or off. We can define a background for our ToggleButtons, which is something we're certainly going to do. We want our app to be pretty, right? And ToggleButtons look terrible out-of-the-box. We can also define the text color similarly to how we define the background. This lines will be red because we haven't built the drawable or color yet. That's okay, we'll get back to that soon! For now, just add it and move on to the button.

Buttons

Ah. The de facto of user interaction. The button that we've added at the end will act as our save button. When we press it, we're going to get all of the values that the user has entered above and do something with them - but not yet! Instead of setting up height, we've decided to set a minHeight of 50dp, which means this element will always be taller than 49dp.

Design Tab

At this point, you should be able to click the design tab at the bottom of the pane. You'll be taken back to the view of an Android Phone, but instead of seeing Hello World, you'll see the view that we've created. You should also see a little notification saying we have rendering problems. Let's go ahead and fix those.

The First issue we're running into is this: Couldn't resolve resource: @drawable/select_button. This is because we set the background of our toggle buttons to reference this and it's a very easy thing to fix - we simply create the file called select_button!

In the far left, right-click on Java and then click on "New", and finally click Android Resource file. You'll be greeted with a menu requesting more information. Fill it out like so:

Now, go ahead and click "Okay." If you did everything properly, you should now be looking at this:

<?xml version="1.0" encoding="utf-8"?>  
<selector xmlns:android="http://schemas.android.com/apk/res/android">

</selector>  

So what exactly is a "Drawable"?

A Drawable is a resource that the Android Operating system (and by association - your app) is able to render to the screen. We can leverage this drawable to define a how a drawable should act under certain conditions - like what it should look like when a user is pressing the button, or when it's active. Drawables can be used in many places in your Android App, but one of the most common use cases is for the Background property on buttons or other widgets. We're going to use our drawable to change the background of those toggle buttons.

We're going to add three new items where the dots are below:

<?xml version="1.0" encoding="utf-8"?>  
<selector xmlns:android="http://schemas.android.com/apk/res/android">  
    ...
</selector>  

First, we're going to add the default button style. We'll create an item element and define that shape and color via child elements within it. Once again, you'll the dots in the above example with this code:

<item>  
    <shape android:shape="rectangle">
        <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp"/>
    </shape>
</item>  

We have a few new elements we're working with here. shape simply defines a shape to be used. Android has several shapes available out of the box, but we can make our own if we'd like. Thankfully, for this tutorial the rectangle will suffice. padding is used to define how much space we'd like this element to have inside the border. This is similar to a margin, except margins grow the space outside of the element, and padding grows the space inside. And with that, we've defined our default state for our toggle buttons. But what if we want our buttons to look different when after a user touches them?

We simply add another item! For this item, add it above the one that you just added, but still within the selector tag.

<item android:state_checked="true">  
    <shape android:shape="rectangle" >
        <corners android:radius="3dip" />
        <stroke android:width="1dip" android:color="@android:color/transparent" />
        <solid android:color="@color/colorAccent" />
        <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp"/>
    </shape>
</item>  

This should look VERY similar to the above example, with a few new things added. First, our item has a property set called android:state_checked set to true. That means that this item will only be shown when the button has "On". To reiterate: The point of the toggle button is a button that can be turned on and off. The next difference you'll notice is that we're defining the corners of our drawable. We can use android:radius to round off our corners. We're also defining stroke which allows us to color the border. We're setting the color to transparent, which is a default color provided by Android.

Next, we're setting solid and the property android:color. solid is the meat and potatoes of the drawable. This color that we set here will fill the entire button. In this case, we're setting it "@color/colorAccent", a reference to a color provided by Android. Later, we'll talk about overriding these colors to brand your app in unique way.

We can add one more item to our list, one that will show when the user is pressing the button. Add the following above the previous item as well:

<item android:state_pressed="true">  
    <shape android:shape="rectangle" >
        <corners android:radius="3dip" />
        <stroke android:width="1dip" android:color="@android:color/transparent" />
        <solid android:color="@color/colorAccent" />
        <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp"/>
    </shape>
</item>  

The only difference with this item is that the state is set to pressed. If we wanted to change the color of our drawable when it's pressed, we could do it with the solid in the last example. Congratulations! You've made your first custom drawable.

Back to Design

In the top of the rightmost pane, if you click activity_add_task.xml, you'll be taken back to design view. You'll still notice that we have a few errors in our popup notification at the bottom of the pane. Let's take care of those, too!

Following the same process as earlier, add a new Android Resource file. This time, however, make sure it's name is "select_button_color" and it's resource type is set to "color". Click "Okay" and you'll be taken to a new file. Replace that file's contents with the following:

<?xml version="1.0" encoding="utf-8"?>  
<selector xmlns:android="http://schemas.android.com/apk/res/android">  
    <item android:state_pressed="true"
        android:color="#000000"/>
    <item android:state_checked="true"
          android:color="#000000"/> 
    <item android:color="#ff000000"/>
</selector>  

This is very similar to the drawable we created earlier, except smaller. Given the drawable and what we've talked about above, this file shouldn't need much of an explanation. The main difference is that the items have a color property set on them. This is because the item is a color and will be used anywhere we can use a color in our Android App. You'll also notice that the colors we specified look different than all of the others. If you're not familiar with that syntax, don't worry, it's called Hexadecimal format and describes the Red, Green and Blue values of the color. You can learn more about that from a quick Google search, if you're interested.

Let's go back to design view. We should no longer see our errors and everything should be rendering properly. Given that it renders properly and we have no errors, we can now build our app. If you're trying to deploy to your phone, you will have to turn on developer options (see below). If you're not deploying to your phone, you'll need an emulator (see below as well). Once you have your device or emulator setup, look for the green play button at the top of Android Studio. Press that, and then press Okay. It'll take some time, but your application will be built and pushed to your device or emulator. It should also automatically open it for you but you may need to look for it in your launcher. Congratulations! You've created your first custom view in Android.

Developer Options

Developer options allows you to push code and apps to your phone without the app store. This is commonly used to test code before deploying it to millions of actual users and is common part of the development cycle. Sadly, the process of turning Developer Options on varies heavily depending on your phone. Your best bet is Googling for how to turn on developer options for your specific phone. Once you've done that and hit play, make sure your phone model is selected in the list. It should also go without saying that your phone needs to be connected to your computer via USB for your app to be pushed to it.

Emulators

Emulators provide you with a quick way to test your android app on your own computer and across multiple devices. They're not as accurate or fun as an actual phone, but unless you'd like to invest thousands of dollars in test devices, they're a great way to test your code on all the mainstream devices. To setup your first emulator, in the toolbar go to Tools > Android > AVD Manager. Then, click Create Virtual Device in the bottom left. Select a phone from the list (I recommend a Nexus) and hit next. Then, download whichever OS you'd like for the phone to run, and then hit next. Name your emulator and hit finish. Now, when you hit play, you'll see your emulator in the list of available devices. Make sure that's selected when you try to push your app.

Closing

Sure, the app doesn't do much yet, but it does look pretty — and now you're more familiar with Android or XML than you were 30 minutes ago! In the next chapter, we'll talk about storing data on android, using SQLite and Android DB Cursors. These are the tools necessary to make sure the data that the user inputs in this view persists from day to day and that they can actually save their task. Hopefully, after our next session, you'll get a better idea of the app we're building, too!

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus