Android Programming with Kotlin for Beginners
上QQ阅读APP看书,第一时间看更新

The Basic Activity project

The next simplest project type with an autogenerated UI is the Basic Activity project. This is the same type of project that we created in Chapter 1, Getting Started with Android and Kotlin. Feel free to open that project up now, but it is recommended to generate a new one so that we can examine it without any of our alterations and additions clouding the discussions.

Let's create a Basic Activity project, as follows:

  1. In Android Studio, select File | New | New Project….
  2. On the Choose your project screen, select the Basic Activity template and click on Next.
  3. Change the Name field to Basic Activity App.
  4. Choose the same package name and save the location as in the previous project.
  5. Be sure to select Kotlin as the language.
  6. Check the Use AndroidX artifacts checkbox as we did previously.
  7. The rest of the settings can be left at their defaults, so just click on Next.

Now we can dig into the files. We won't look at everything in the same detail that we did for the Empty Activity project; we will just look at the differences and extra bits.

Exploring the Basic Activity project

Let's compare the Kotlin code first. Take a look at the MainActivity.kt tab in the code editor. They both contain a class called MainActivity. The difference is in the number of functions and the content of the onCreate function.

As already stated, the Basic Activity project has more to it than the Empty Activity project.

Tip

You can open as many instances of Android Studio as you like. If you want to compare projects side by side, select File | Open and choose the project, then when prompted, select New Window to open the project without closing any that are already open.

The first difference is that there is some extra code in the onCreate function.

The MainActivity.kt file

I mentioned very briefly, back in Chapter 2, Kotlin, XML, and the UI Designer, the interconnections that exist in the Kotlin code and the XML code. Let's look through the resources files and point out the XML files that this Kotlin code points to.

Here is the relevant Kotlin code from the onCreate function; I have slightly reformatted it to make it more readable in a book:

setSupportActionBar(toolbar)

fab.setOnClickListener { view ->
   Snackbar.make(view, "Replace with your own action",
               Snackbar.LENGTH_LONG)
               .setAction("Action", null).show()
}

Understanding this code fully will take quite a few more chapters, but to point out where this code uses files in the resources will only take a moment, and will then leave us even more aware of the components that make up our projects.

The code refers to two more resources compared to the Empty Activity project. The first is toolbar, the second is fab, and both refer to an XML file that we will see next.

If you open the res/layout folder in the project window, you can see that things look slightly differently to how they did in the Empty Activity project:

There are now two files that were autogenerated. We will explore the content_main.xml file and gain an understanding of why it is required shortly.

The activity_main.xml file

For now, open up the activity_main.xml file and you will see there are some elements to represent both toolbar and fab. By referring to these elements, the Kotlin code is setting up the toolbar and the floating action bar ready for use. The XML code, as we have come to expect, describes what they look like.

Here is the XML code for the toolbar:

<androidx.appcompat.widget.Toolbar
   android:id="@+id/toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:background="?attr/colorPrimary"
   app:popupTheme="@style/AppTheme.PopupOverlay" />

Notice that it refers to a Toolbar, a color, and a style, as well as some others. It is the line that starts with android:id…, which declares a widget of type Toolbar and its @+id/toolbar value, which makes it accessible via the toolbar instance name in the Kotlin code.

For clarity, this is the toolbar in the actual working app:

Here is the XML code for the floating action button. I have slightly reformatted the first line of the code onto two lines:

<com.google.android.material.floatingactionbutton.
         FloatingActionButton

   android:id="@+id/fab"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="bottom|end"
   android:layout_margin="@dimen/fab_margin"
   app:srcCompat="@android:drawable/ic_dialog_email" />

Notice that it has an id attribute of fab. It is through this id attribute that we gain access to the floating action button in our Kotlin code.

Now, fab in our Kotlin code can directly control the floating action button and all its attributes. In Chapter 13, Bringing Android Widgets to Life, we will learn how to do this in detail.

Here is the floating action button in the actual app:

It is evident that I haven't explained the code in detail; there is no point at this stage. Instead, make a mental note of the interconnections, as follows:

  • XML files can refer to other XML files.
  • Kotlin can refer to XML files (and, as we will see soon, other Kotlin files).
  • In Kotlin, we can grab control of a specific part of the UI in an XML file via its id attribute.

We have seen enough from this file; let's move on and dip into the remaining files.

The extra functions in MainActivity.kt

So, what do the functions do, when are they called, and who exactly calls them?

The next difference is this extra function, as follows:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
  // Inflate the menu; this adds items to 
  // the action bar if it is present.
  menuInflater.inflate(R.menu.menu_main, menu)
  return true
}

This code prepares (inflates) the menu that is defined in the menu_main.xml file. And, just as with onCreate, the function is overridden and it is called by the operating system directly.

Then there is yet another function, as follows:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
  // Handle action bar item clicks here. The action bar will
  // automatically handle clicks on the Home/Up button, so long
  // as you specify a parent activity in AndroidManifest.xml.
  return when (item.itemId) {
        R.id.action_settings -> true
        else -> super.onOptionsItemSelected(item)
  }
}

This function is also overridden and is called directly by the operating system. It handles what happens when an item (or option) from the menu is selected by the user. At the moment, it handles just one option, which is the settings option, and it currently takes no action.

The preceding code determines whether the settings menu option was clicked on; if it was, then the return when code executes, and control is returned to whatever part of the app was executing before it was interrupted by the user clicking on the Settings menu option. We will learn more about the Kotlin when keyword in Chapter 8, Kotlin Decisions and Loops.

We nearly know enough for now; don't worry about memorizing all these connections. We will be coming back to each connection, investigating more deeply, and cementing our understanding of each.

So, why do we need that second file in the res/layout folder?

The content_main.xml file

The MainActivity.kt file calls setContentView on R.layout.activity_main. Then, in turn, activity_main has this line of code highlighted:

…
</com.google.android.material.appbar.AppBarLayout>

<include layout="@layout/content_main" />

<com.google.android.material.floatingactionbutton
  .FloatingActionButton
…

The highlighted line of code does include the content_main file. So, just after the app bar is added to the layout, the execution branches to content_main, where all its XML code is turned into the UI; then, the execution goes back to activity_main and the floating action bar is added to the layout. We will use include in Chapter 5, Beautiful Layouts with CardView and ScrollView, when we build some neat scrolling CardView layouts and separate the code that defines CardView from the actual contents of CardView.