From Layout XML to View Objects

How do XML elements in activity_main.xml become View objects? The answer starts in the MainActivity class.

When you created the GeoQuiz project, a subclass of Activity named MainActivity was created for you. The class file for MainActivity is in the app/java directory of your project.

A quick aside about the directory name before we get into how layouts become views: This directory is called java because Android originally supported only Java code. In your project, because you configured it to use Kotlin (and Kotlin is fully interoperable with Java), the java directory is where the Kotlin code lives. You could create a kotlin directory and place your Kotlin files there, but that would provide no real benefits and requires additional configuration, so most developers just place their Kotlin files in the java directory.

Return to the MainActivity.kt file and take a look at its contents:

    package com.bignerdranch.android.geoquiz

    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle

    class MainActivity : AppCompatActivity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }

(Wondering what AppCompatActivity is? It is a subclass of Android’s Activity class that provides compatibility support for older versions of Android. You will learn much more about AppCompatActivity in Chapter 15.)

If you are not seeing all of the import statements, click the ... next to the word import to reveal them.

This file has one Activity function: onCreate(Bundle?).

The onCreate(Bundle?) function is called when an instance of the activity subclass is created. When an activity is created, it needs a UI to manage. To give the activity its UI, you call Activity.setContentView(layoutResID: Int).

This function inflates a layout and puts it onscreen. When a layout is inflated, each view in the layout file is instantiated as defined by its attributes. You specify which layout to inflate by passing in the layout’s resource ID.

Resources and resource IDs

A layout is a resource. A resource is a piece of your application that is not code – things like image files, audio files, and XML files.

Resources for your project live in a subdirectory of the app/res directory. In the project tool window, you can see that activity_main.xml lives in res/layout/. Your strings file, which contains string resources, lives in res/values/.

To access a resource in code, you use its resource ID. The resource ID for your layout is R.layout.activity_main.

You did not define R.layout.activity_main yourself. As a part of compiling your app, the build process automatically generates that resource ID for you. In fact, the build process generates resource IDs for all the resources in your project.

During the compilation and packaging of your app, the build tools generate a class known as the R class. This class contains a long list of IDs as integer constants, allowing you to access and use your resources in your application. When referencing R.layout.activity_main, you are actually referencing an integer constant named activity_main within the layout inner class of R.

As you add, remove, and change resources, the build process will automatically update the file in order to maintain the correct mapping between resources and their IDs. Here is an example of what your R class looks like in Java:

    package com.bignerdranch.android.geoquiz;

    public final class R {
        public static final class anim {
            ...
        }
        ...
        public static final class id {
            ...
        }
        public static final class layout {
            ...
            public static final Int activity_main=0x7f030017;
        }
        public static final class mipmap {
            public static final Int ic_launcher=0x7f030000;
        }
        public static final class string {
            ...
            public static final Int app_name=0x7f0a0010;
            public static final Int false_button=0x7f0a0012;
            public static final Int question_text=0x7f0a0014;
            public static final Int true_button=0x7f0a0015;
        }
    }

Your strings also have resource IDs. You have not yet referred to a string in code, but if you did, it would look like this:

    setTitle(R.string.app_name)

Android generated a resource ID for the entire layout and for each string, but it did not generate resource IDs for the individual views in activity_main.xml. Not every view needs a resource ID. In this chapter, you will only interact with the two buttons in code, so only they need resource IDs.

To generate a resource ID for a view, you include an android:id attribute in the view’s definition. In activity_main.xml, add an android:id attribute to each button. (You will need to switch to the Code tab to do this.)

Listing 1.3  Adding IDs to Buttons (res/layout/activity_main.xml)

<LinearLayout ... >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        android:text="@string/question_text" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button" />

        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button" />

    </LinearLayout>

</LinearLayout>

Notice that there is a + sign in the values for android:id but not in the values for android:text. This is because you are creating the resource IDs and only referencing the strings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset