Android Tutorial for Beginners: Part 2

An Android Tutorial that shows you how to make your first app app step-by-step, using Android Studio! By Darryl Bayliss.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 7 of this article. Click here to view the first page.

Buttons and Listeners

It’s time to build on your TextView and get more interactive! Next up is a Button.

Add a Button to activity_main.xml, directly after your TextView:

<!-- Set OnClickListener to trigger results when pressed -->
<Button
    android:id="@+id/main_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:layout_marginLeft="20dp"
    android:text="@string/button" />

Notice there’s an XML comment above the Button, a reminder of how to trigger results.

The layout_margin attributes simply add 20 density-independent pixels of space above and to the left of the Button to keep your layout from looking cramped. Remember that the value of 20 will be scaled by the screen density of the device to get an actual pixel value.

You’ve probably noticed @string/button under the button text property appears in red. If you hover over it, you’ll see that the symbol cannot be resolved – and that’s because you haven’t yet defined it.

Open strings.xml and add the following line to the bottom to resolve this:

<string name="button">Update The TextView</string>

Next, open MainActivity.java and add the following right below the previous line you added to include a TextView variable:

Button mainButton;

Now add the following code to the end of onCreate, after the code you added earlier:

// 2. Access the Button defined in layout XML
// and listen for it here
mainButton = (Button) findViewById(R.id.main_button);
mainButton.setOnClickListener(this);

Again, you see the same three steps as when you added code to access the TextView:

  1. You add an id to the View in XML. Or, in this case, you add a view with an id attribute.
  2. You access that View in code by using the id.
  3. You call methods on that View.

This time, the method you called on the Button is setOnClickListener. What you put in the parentheses of that method becomes the answer to this question: Which Object is going to respond when this Button gets pressed?

To answer that question with simply the word this seems a little curt and unspecific, but Java knows that it means MainActivity itself is your intended listener.

This means that MainActivity has to implement the View.OnClickListener interface. If that sentence doesn’t make much sense to you, I suggest finding an intro on what an interface is and how to create one, like this one.

If have an iOS/Objective-C background, an interface is comparable to a protocol. In fact, in object oriented programming the words protocol and interface are used interchangeably.

Note: An interface is like part of a job description. If I’m a young, ambitious Java object, and I want to be able to put a particular certification on my resume, there are a few methods I have to be comfortable and capable of performing. The interface is like the checklist I need to pass, or “implement.”

If have an iOS/Objective-C background, an interface is comparable to a protocol. In fact, in object oriented programming the words protocol and interface are used interchangeably.

Android Studio is smart and can help you do the implementation. Simply single-click on this, which is underlined in red, indicating an issue (in this case the fact that MainActivity currently does not support the necessary interface). Then, when a red light bulb appears at the beginning of the line, click on it and select Make ‘MainActivity’ implement ‘android.view.View.OnClickListener’.

implement_onclick

Simply click OK on the next dialog, which lets you know which method(s) Studio will automatically create for you.

auto_generate_method

Studio then generates the code necessary to make your MainActivity qualify as a union-certified OnClickListener.

First, it added a bit to the class declaration indicating that the Activity implements a specific interface:

public class MainActivity extends ActionBarActivity implements View.OnClickListener

Second, Studio added a stub for a method you need to implement in order to get your OnClickListener license (other interfaces may require more than one method to be implemented): onClick. This method fires when your Button gets pressed.

@Override
public void onClick(View v) {
        
}

The method currently does nothing. So add the following code to onClick to make it do something:

    
// Test the Button
mainTextView.setText("Button pressed!");    

Can you tell from the code what should happen? Run your app and see if you’re right…

button_pressed

The app now changes the text in the TextView when you press the Button. Cool! You’ll be putting this Button to even better use later — to submit input.

Adding a Visual and Nested Layouts

It’s always fun to include images in your UI. So how about adding an ImageView to show a little icon? Along the way, you’ll also get to see how a nested LinearLayout works.

First off, what image will you show? Well, it’s easiest to start with the image you’re given by default. It’s already in your project and here’s where to find it.

Use the Project Navigator to expand the res/drawable directory:

ic_launcher

You can see a folder with multiple copies of the same image within res. Notice that the file names have brackets at the end that look like they contain screen density abbreviations.

Indeed, those abbreviations correspond to the pixel density buckets used to classify Android devices in dots per inch (dpi):

  • mdpi: medium
  • hdpi: high
  • xhdpi: extra high
  • xxhdpi: extra extra high

You can even create your own xxxhdpi folder where you can place images for devices with even higher pixel densities. Personally, I think they should use Roman numerals for the next level up and call it xlhdpi, but on second thought that would probably be a terribly confusing way to go…

Look inside the drawable directories. You’ll see a file named ic_launcher.png. This is simply the default launch image you’re given, at several different sizes for different screens. The Android system will pick the right one for the device.

Now head back to activity_main.xml and replace the following section:

<!-- Set OnClickListener to trigger results when pressed -->
<Button
    android:id="@+id/main_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:layout_marginLeft="20dp"
    android:text="@string/button" />

With this:

<!-- This nested layout contains views of its own -->
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <!-- Set OnClickListener to trigger results when pressed -->
    <Button
        android:id="@+id/main_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:text="@string/button" />
    <!-- Shows an image from your drawable resources -->
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:src="@drawable/ic_launcher" />
    <!-- Closing tag for the horizontal nested layout -->	
</LinearLayout>

You just added a new LinearLayout inside the existing root LinearLayout layout, directly underneath the TextView as its new sibling. You also moved the existing Button into the nested layout and added a new ImageView, as well.

By wrapping your Button in a second, horizontal LinearLayout, you are able to place a Button and an ImageView side-by-side horizontally, even as the root layout has a vertical orientation.

As for the ImageView itself, the important attribute is src, to which you give your drawable image resource. Note the format you use to reference the drawable image. You need to prefix the file name of your image (minus the file type) with @drawable/.

Run the app, and you’ll see the new image right beside the button!

nested_layout_imageview