Introduction to Android Activities with Kotlin

Learn about one of the most important concepts within Android apps with this introduction to Android activities tutorial, using Kotlin! By Steve Smith.

4.3 (22) · 1 Review

Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Configuration Changes

You need the ability to delete entries from Forget Me Not.

Still in MainActivity.kt, at the bottom of the class add:

private fun taskSelected(position: Int) {
  // 1
  AlertDialog.Builder(this)
    // 2
    .setTitle(R.string.alert_title)
    // 3
    .setMessage(taskList[position])
    .setPositiveButton(R.string.delete, { _, _ ->
      taskList.removeAt(position)
      adapter.notifyDataSetChanged()
    })
    .setNegativeButton(R.string.cancel, {
      dialog, _ -> dialog.cancel()
    })
    // 4
    .create()
    // 5
    .show()
}

In a nutshell, you’re creating and showing an alert dialog when you select a task from the list. Here is the step-by-step explanation:

  1. You create an AlertDialog.Builder which facilitates the creation of an AlertDialog.
  2. You set the alert dialog title.
  3. You set the alert dialog message to be the description of the selected task. Then you also implement the PositiveButton to remove the item from the list and refresh it, and the NegativeButton to dismiss the dialog.
  4. You create the alert dialog.
  5. You display the alert dialog to the user.

Update the OnItemClickListener of the taskListView in onCreate():

taskListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
  taskSelected(position)
}

Your app won’t compile though until you define some strings. It’s good practice to keep text you want in your app separate from the code. The reason is so that you can easily change it, which is especially useful for text that you use in multiple places. It’s also handy for those times you need to translate your app into another language.

To configure the strings, open res/values/strings.xml and within the resources element add:

<string name="alert_title">Task</string>
<string name="delete">Delete</string>
<string name="cancel">Cancel</string>

Build and run the app. Tap on one of the tasks. You’ll see an alert dialog with options to CANCEL or DELETE the task from the list:

Now try rotating the device. (Make sure you have rotation in the device settings set to auto-rotate.)

As soon as you rotate the device, the alert dialog is dismissed. This makes for an unreliable, undesirable user experience — users don’t like it when things just vanish from their screen without reason.

Handling Configuration Changes

Configuration changes, such as rotation, keyboard visibility and so on, cause an activity to shut down and restart. You can find the full list of system events that cause an activity to be recreated here.

There are a couple of ways you can handle a configuration change.

One way is as follows. In AndroidManifest.xml, find the start tag:

<activity android:name=".MainActivity">

And change it to:

<activity android:name=".MainActivity" android:configChanges="orientation|screenSize">

Here, you declare that your MainActivity will handle any configuration changes that arise from a change in orientation or screen size. This simple line prevents a restart of your activity by the system, and it passes the work to MainActivity.

You can then handle these configuration changes by implementing onConfigurationChanged(). In MainActivity.kt, add the following method after onStop():

override fun onConfigurationChanged(newConfig: Configuration?) {
  super.onConfigurationChanged(newConfig)
}

Here you’re just calling the superclass’s onConfigurationChanged() method since you’re not updating or resetting any elements based on screen rotation or size.

onConfigurationChanged() is passed a Configuration object that contains the updated device configuration.

By reading fields in this newConfig, you can determine the new configuration and make appropriate changes to update the resources used in your interface.

Now, build and run the app and rotate the device again. This time, the dialog stays in place until you dismiss it.

An alternative way to handle configuration changes is to retain a stateful object that’s carried forward to the recreated instance of your activity. You can accomplish this by implementing the onSaveInstanceState() callback.

When you do this, the system saves your activity’s state in a Bundle, and you can restore it when you implement the corresponding onRestoreInstanceState() callback. However, the Bundle is not designed to hold large data sets such as bitmaps, and it can only store data that is serializable.

The downside of the stateful object solution is that serializing and deserializing the data during a configuration change can come at a high cost. It can consume a lot of memory and slow down the activity restart process.

In such instances, retaining a Fragment is currently the most preferable way to handle a configuration change. You can learn more about fragments and how to use them to retain information when your activity is restarted in our Android Fragments Tutorial.

Where To Go From Here?

Congratulations! You have just learned the basics of using activities in Android and now have an excellent understanding of the ever-important activity lifecycle.

You covered quite a few concepts, including:

  • How to create an activity
  • How to stop an activity
  • How to persist data when an activity stops
  • How to work around a configuration change

congratulations

You can download the completed project using the Download materials button at the top or bottom of the tutorial. If you’re still hungry for more, check out Google’s documentation.

I hope you enjoyed this introduction to Android activities tutorial, and if you have any questions, comments, or awesome modifications to this project app please join the forum discussion and comment below!