Make Your First Android App: Part 2/3
Learn to enhance the app you created in the first part on how to make your first Android app and to add new UI controls to add new functionality. By Matt Luedke.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Make Your First Android App: Part 2/3
55 mins
This tutorial is the second of three parts. If you’re looking to start from scratch, Part One is the tutorial for you!
The first part of this series covered a lot of zoomed-out Android concepts, as well as the general structure of Android projects. In this part of the tutorial, you’ll learn more “on the ground” Android: how a layout file works and the specifics of Android layouts and views.
By the time you’re done with this section, you’ll have an app with:
- An image from a PNG file;
- An editable text field for writing messages;
- A button to submit your input;
- A text view that shows your most recent message;
- A list that displays all your messages;
- An option to share your message through Facebook, Twitter, SMS or email; and
- A greeting that saves and retrieves your name each time you open the app.
You should already be at the point where you have a “Hello World” app running on your emulator or device. At the end of the last section, you changed the text so that it greets you personally, like mine:
It’s great that you’ve come this far — but now it’s time to take it to the next level! There’s a lot to do, so let’s get to it!
Getting Started
Looking ahead, the first thing you should do is check that you’re making your app as simple as possible. You don’t want to introduce additional complexity unless it’s needed since extra complexity in how something is implemented means that it takes more time and requires more work if you were to later modify the bits with the extra complexity.
The project that Android Studio creates by default gives you a structure that works well for a lot of apps. It uses a Fragment
. Fragments are like sub-activities. They contain UI elements that could either take up the whole screen or just a portion of it. They’re controlled by their parent Activity
and can be swapped out for another Fragment
quite easily.
But for your first app, the additional complexity of a Fragment
isn’t really needed. So, you’ll remove this default Fragment
setup.
First, open MainActivity.java and find the following section inside onCreate
:
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
Select and delete that bit of code.
Second, scroll to the bottom of the file and find the section defining the PlaceholderFragment
class:
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
Carefully select and delete the whole class definition, making sure that the final closing bracket for MainActivity
is not removed.
Next, open res/layout/fragment_main.xml. After opening the file, you may have to switch the editor to Text mode if you can’t see the raw XML. Click the appropriate tab at the bottom of the editor pane as shown below.
Select all the text inside fragment_main.xml and copy it. Then, open res/layout/activity_main.xml and replace its contents with the former contents of fragment_main.xml.
There’s Just a bit of clean up left to do. Remove this line:
xmlns:tools=http://schemas.android.com/tools
And this one:
tools:context=".MainActivity$PlaceholderFragment"
Note: The above line might not look exactly like that. It might have the .MainActivity$PlaceholderFragment
bit prefixed by the package name you set for your project. So don’t be confused if you the line doesn’t look exactly the same as the one above :] Also, do not remove the closing angle bracket if the above line is on the last line of that particular section.
Note: The above line might not look exactly like that. It might have the .MainActivity$PlaceholderFragment
bit prefixed by the package name you set for your project. So don’t be confused if you the line doesn’t look exactly the same as the one above :] Also, do not remove the closing angle bracket if the above line is on the last line of that particular section.
And these four lines which set the padding:
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
After all of these steps, your activity_main.xml should look something like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Now, right-click on fragment_main.xml on the left pane of Android Studio and select the Delete… option from the context menu.
Now that you’ve finished that bit of cleaning up, you’re all set to work with a simple Activity
. And it’s time to learn how to make a layout for one!
XML Layout Basics
Android layouts are in XML format, in the form of a tree with a single root and a hierarchy of views. The hierarchy is very strict and straightforward: each view in the tree is termed the parent of the views it contains and the child of the view that contains it.
Open res/layout/activity_main.xml. You can see the XML for your activity here. There is a parent RelativeLayout
and a child TextView
.
Look at the TextView
specifically. You can see that it contains three attributes. Of those, two are present in every view you’ll ever put into your Android layouts: layout_width
and layout_height
. The values for these attributes can take several forms:
-
wrap_content
: This constant value specifies that the view will be just large enough to fit whatever is inside it, whether that’s an image, text or child view. -
match_parent
: This constant sets the view to be as big as its parent. -
Explicit values: You could set the dimension to a specific number of pixels (Ex:
5px
), but it is usually wiser to use density independent pixels (Ex:5dp
). Adp
is a pixel on a “medium-density” (mdpi
) device, and the number of actual pixels automatically scales for devices designated as low-density (ldpi
), high-density (hdpi
), extra-high-density (xhdpi
), etc.
In other words, using straight-up pixels would result in your views being all sorts of crazy sizes, depending on whether a device has 160 pixels per inch or 300 pixels per inch, or what have you. Who knows! Let the Android system take care of the scaling and just use dp
.
Note: Designations like mdpi
and hdpi
are only general categories. Actual pixel densities are even more variable, but they are all given the same scaling factor regardless. So dp
scaling, while convenient, is not an exact science.
iOS Developers should be familiar with a similar practice of density independence, using “points” instead of pixels in their layouts to account for early iPhone screens not having Retina displays.
Note: Designations like mdpi
and hdpi
are only general categories. Actual pixel densities are even more variable, but they are all given the same scaling factor regardless. So dp
scaling, while convenient, is not an exact science.
iOS Developers should be familiar with a similar practice of density independence, using “points” instead of pixels in their layouts to account for early iPhone screens not having Retina displays.
The final attribute of the TextView
is simply text
, in which you specify the text to be displayed. This attribute is a good example of how different views respond to different attributes. Adding a text
attribute to a RelativeLayout
or a Space
wouldn’t accomplish anything because, unlike the TextView
, they wouldn’t know what to do with it.
But the value of the attribute, @string/hello_world
, isn’t what’s displaying, is it? What you specify in your layout file is not the actual string to be displayed but rather a string resource ID identifying the actual text. That way, all your app’s copy can be in one place – res/values/strings.xml.
Now let’s look at the parent node in the XML: RelativeLayout
. What’s going on there?