Android Kotlin – Building a Times Tables App – Part 1

Google’s Android Studio is a pretty awesome tool for building Android apps, but after building a times tables app in python and HTML, I’ll say doing an Android version was a bit more complicated. But with a little bit of knowledge about how the basics of Android Studio works along with some knowledge of Kotlin, you can have a basic app up and running in very little time. Today I’m building an app that is basically flash cards for times tables, with a couple different modes. I’ve split this up into two posts since there’s a fair amount of code.

Part 2 of this post is here.

When I wrote this, I was using Android Studio Arctic Fox | 2020.3.1 Patch 2.

The full code for this project is on my Github account:

https://github.com/jamesmcclay/android_kotlin_times_tables

Create a new project

We start by creating a new project, with an empty activity.

New project screen in Android Studio

Give your project a name, and make sure to set the language as Kotlin. Click finish, and you have a brand new project!

Write the layout code

Android Studio takes you to the MainActivity.kt file off the bat, but we’re going to jump into the layout file and create the interface elements. At the top of the screen, you should see a tab that says activity_main.xml, that’s where we can create the first page elements of app.

Opening up activity_main.xml, you’ll need to click on “split” near the top right so you can see the code as well as a rending of it on a mock phone. There’s a bunch of code already in there but you can delete all that.

First I’m going to create a RelativeLayout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</RelativeLayout>

If you just type “Re”, RelativeLayout will probably autopopulate and you can press enter to get it and a bunch of pre-written code for you. No need to type all that stuff.

Text items

Inside the RelativeLayout (between the opening and closing <RelativeLayout> tags), I’ll create some text. These will just be banners introducing the app and instructing the user to enter a table to practice. This can be done with the element TextView:

    <TextView
        android:id="@+id/textview_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100dp"
        android:text="James McClay's\nTimes Tables!"
        android:textAlignment="center"
        android:textSize="32sp" />

    <TextView
        android:id="@+id/textview_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textview_title"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:text="Practice all tables\n Or enter a table to practice:"
        android:textAlignment="center"
        android:textSize="24sp" />

I thought about commenting all these to explain what they’re doing, but it seems like they’re all pretty self-explanatory. It’s basically just putting some static text on the layout of the app, centering it, setting the font size, etc.

Next we’ll create a text entry field where the user can either leave it blank to practice all times tables or enter a specific one. This is done with the element EditText:

    <EditText
        android:id="@+id/edittext_timestable"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textview_select"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:hint="All tables"
        android:inputType="number"
        android:textAlignment="center"
        android:textSize="24sp" />

All elements have been given an "@+id", and using layout_below we can tell elements to go below another one.

Button and radio group

Next we’ll need a start button to send the user to the view that shows times tables questions. A button can be created with Button:

    <Button
        android:id="@+id/button_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/edittext_timestable"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp"
        android:text="Start!" />

Finally, we’ll create a RadioGroup to hold two radio button buttons. I thought having a normal, sequential mode as well as a random mode would be beneficial. The RadioGroup means that only one RadioButton can be selected in the group. Also, RadioButtons have a special property called onClick, where you can specify what function to run when one of the buttons is clicked and selected.

    <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_start"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        >

    <RadioButton
        android:id="@+id/radio_normal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onRadioButtonClicked"
        android:text="Normal Mode"
        />

    <RadioButton
        android:id="@+id/radio_random"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onRadioButtonClicked"
        android:text="Random Mode" />
    </RadioGroup>

Remember, all of that stuff went in-between the RelativeLayout tags. Ok, now we’re ready for the Kotlin code.

onCreate function

You will probably need to add a snippet of code to your app’s build.gradle file so you can “bind” your Kotlin code to the layout file. Be careful – there are two of these files. You want the one that is inside “app” directory, not the one that’s in the root directory. In build.gradle, in the android block, paste this snippet and sync gradle:

buildFeatures {
    viewBinding = true
}

Next let’s write our code in the onCreate function that’s given to us by Android Studio:

class MainActivity : AppCompatActivity() {

    var mode: String = "normal" //represents what radio button user selected

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding = ActivityMainBinding.inflate(layoutInflater) //bind to layout file
        setContentView(binding.root)

        val button = binding.buttonStart //get the start button
        button.setOnClickListener {
            val theIntent = Intent(this, TableActivity::class.java)
            var table = binding.edittextTimestable.text.toString() // get what table the user entered
            if (table == "") {
                table = "0" //if the user entered nothing, meaning all tables, set to 0 so toInt() won't fail.
            }
            theIntent.putExtra("mode", mode) // send mode to next screen
            theIntent.putExtra("table", table) // send table to next screen
            startActivity(theIntent)
        }
    }
}

I’ve created a global variable (I believe the Kotlin word is “property”) called mode to hold what radio button the user selected. The Intent stuff is just standard boilerplate code to send the user to the next screen. The next screen’s activity will be called TableActivity, which this bit Intent(this, TableActivity::class.java) has TableActivity in it.

You’ll notice we’ve attached mode and table to the intent so the next screen’s code can access it. You can see where table is retrieved and set, but you might be wondering how mode is set. We’ll do that next.

onRadioButtonClicked function

I took this code directly from the Android Studio documentation, and substituted my radio button id’s and mode property. We specified the onRadioButtonClicked function in the Radio Button XML code earlier.

fun onRadioButtonClicked(view: View) {
    if (view is RadioButton) {
        // Is the button now checked?
        val checked = view.isChecked

        // Check which radio button was clicked
        when (view.getId()) {
            R.id.radio_normal ->
                if (checked) {
                    this.mode = "normal"
                }
            R.id.radio_random ->
                if (checked) {
                    this.mode = "random"
                }
        }
    }
}

This basically just runs some logic to see which button is clicked, and then set the value of mode.

Try it out!

The app looks pretty good so far!

On the next post – I’ll build the screen where the user can actually practice times tables. Happy coding!

Check out part 2!

Leave a Reply

Your email address will not be published.