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.
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
Introduction to Android Activities with Kotlin
30 mins
Configuring an Activity
Keeping the activity lifecycle in mind, take a look at an activity in the sample project. Open MainActivity.kt, and you’ll see that the class with its onCreate()
override looks like this:
class MainActivity : AppCompatActivity() {
// 1
private val taskList: MutableList<String> = mutableListOf()
private val adapter by lazy { makeAdapter(taskList) }
override fun onCreate(savedInstanceState: Bundle?) {
// 2
super.onCreate(savedInstanceState)
// 3
setContentView(R.layout.activity_main)
// 4
taskListView.adapter = adapter
// 5
taskListView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> }
}
// 6
fun addTaskClicked(view: View) {
}
// 7
private fun makeAdapter(list: List<String>): ArrayAdapter<String> =
ArrayAdapter(this, android.R.layout.simple_list_item_1, list)
}
Here’s a play-by-play of what’s happening above:
- You initialize the activity’s properties, which include an empty mutable list of tasks and an adapter initialized using
by lazy
. - You call
onCreate()
on the superclass — remember that this is (usually) the first thing you should do in a callback method. There are some advanced cases in which you may call code prior to calling the superclass. - You set the content view of your activity with the corresponding layout file resource.
- Here you set up the adapter for
taskListView
. The reference totaskListView
is initialized using Kotlin Android Extensions, on which you can find more info here. This replacesfindViewById()
calls and the need for other view-binding libraries. - You add an empty
OnItemClickListener()
to theListView
to capture the user’s taps on individual list entries. The listener is a Kotlin lambda. - An empty on-click method for the “ADD A TASK” button, designated by the activity_main.xml layout.
- A private function that initializes the adapter for the list view. Here you are using the Kotlin = syntax for a single-expression function.
Note: To learn more about ListViews
and Adapters
, refer to the Android Developer docs.
For larger data sets than you would encounter in this example, a RecyclerView
and RecyclerView.ViewHolder
would be recommended. See the RecyclerView docs for more information.
Note: To learn more about ListViews
and Adapters
, refer to the Android Developer docs.
For larger data sets than you would encounter in this example, a RecyclerView
and RecyclerView.ViewHolder
would be recommended. See the RecyclerView docs for more information.
Your implementation follows the theory in the previous section — you’re doing the layout, adapter and click listener initialization for your activity during creation.
Starting an Activity
In its current state, the app is a fairly useless lump of ones and zeros because you can’t add anything to the to-do list. You have the power to change that, and that’s exactly what you’ll do next.
In the MainActivity.kt file you have open, add a property to the top of the class:
private val ADD_TASK_REQUEST = 1
You’ll use this immutable value to reference your request to add new tasks later on.
Then add this import statement at the top of the file:
import android.content.Intent
And add the following implementation for addTaskClicked()
:
val intent = Intent(this, TaskDescriptionActivity::class.java)
startActivityForResult(intent, ADD_TASK_REQUEST)
When the user taps the “ADD A TASK” button, the Android OS calls addTaskClicked()
. Here you create an Intent
to launch the TaskDescriptionActivity
from MainActivity
.
Note: There will be a compile error since you have yet to define TaskDescriptionActivity
.
Note: There will be a compile error since you have yet to define TaskDescriptionActivity
.
You can start an activity with either startActivity()
or startActivityForResult()
. They are similar except that startActivityForResult()
will result in onActivityResult()
being called once the TaskDescriptionActivity
finishes. You’ll implement this callback later so you can know if there is a new task to add to your list or not.
But first, you need a way to enter new tasks in Forget Me Not — you’ll do so by creating the TaskDescriptionActivity
.
Note: Intents
are used to start activities and pass data between them. For more information, check out the Android: Intents Tutorial
Note: Intents
are used to start activities and pass data between them. For more information, check out the Android: Intents Tutorial
Creating an Activity
Android Studio makes it very easy to create an activity. Just right-click on the package where you want to add the activity — in this case, the package is com.raywenderlich.android.forgetmenot. Then navigate to New\Activity, and choose Empty Activity, which is a basic template for an activity:
On the next screen, enter TaskDescriptionActivity as the Activity Name and Android Studio will automatically fill the other fields based on that.
Click Finish and put your hands in the air to celebrate. You’ve just created your first activity!
Android Studio will automatically generate the corresponding resources needed to create the activity. These are:
- Class: The class file is named TaskDescriptionActivity.kt. This is where you implement the activity’s behavior. This class must subclass the Activity class or an existing subclass of it, such as AppCompatActivity.
-
Layout: The layout file is located under
res/layout/
and named activity_task_description.xml. It defines the placement of different UI elements on the screen when the activity is created.
The layout file created from the Empty Activity template in Android Studio 3.0 and above defaults to using a ConstraintLayout for the root view group. For more information on ConstraintLayout, please see the android developer docs here.
In addition to this, you will see a new addition to your app’s AndroidManifest.xml file:
<activity android:name=".TaskDescriptionActivity"></activity>
The activity
element declares the activity. Android apps have a strong sense of order, so all available activities must be declared in the manifest to ensure the app only has control of activities declared here. You don’t want your app to accidentally use the wrong activity, or even worse, have it use activities that are used by other apps without explicit permission.
There are several attributes that you can include in this element to define properties for the activity, such as a label or icon, or a theme to style the activity’s UI.
android:name
is the only required attribute. It specifies the activity’s class name relative to the app package (hence the period at the beginning).
Now build and run the app. When you tap on ADD A TASK, you’re presented with your newly generated activity!
Looking good, except for the fact that it’s lacking substance. Now for a quick remedy to that!
In your newly generated TaskDescriptionActivity, paste the following into your class file, overwriting anything else except the class declaration and its brackets.
// 1
companion object {
val EXTRA_TASK_DESCRIPTION = "task"
}
// 2
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_description)
}
// 3
fun doneClicked(view: View) {
}
Note: You can quickly fix any missing imports that Android Studio complains about by placing your cursor on the item and pressing option+return on Mac or Alt+Enter on PC.
Note: You can quickly fix any missing imports that Android Studio complains about by placing your cursor on the item and pressing option+return on Mac or Alt+Enter on PC.
Here, you’ve accomplished the following:
- Used the Kotlin companion object for the class to define attributes common across the class, similar to static members in Java.
- Overriden the
onCreate()
lifecycle method to set the content view for the activity from the layout file. - Added an empty click handler that will be used to finish the activity.
Jump over to your associated layout in res/layout/activity_task_description.xml and replace everything with the following:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
tools:context="com.raywenderlich.android.forgetmenot.TaskDescriptionActivity">
<TextView
android:id="@+id/descriptionLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/default_padding"
android:text="@string/description"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/descriptionText"
android:layout_width="match_parent"
android:layout_height="100dp"
android:inputType="textMultiLine"
android:padding="@dimen/default_padding"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/descriptionLabel" />
<Button
android:id="@+id/doneButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doneClicked"
android:padding="@dimen/default_padding"
android:text="@string/done"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/descriptionText" />
</android.support.constraint.ConstraintLayout>
Here you change the layout so there is a TextView
prompting for a task description, an EditText
for the user to input the description, and a Done button to save the new task.
Run the app again, tap ADD A TASK and your new screen will look a lot more interesting.