Welcome to part-3 of this Tic Tac Toe Android Kotlin beginner tutorial series where we will be making a fun Tic Tac Toe game app. To go to part 1 of this series, click here
In this tutorial, we will add click listeners (do something when a button is clicked) to all the buttons in the layout created in the previous tutorial. We’ll set up all the variables we need for our app and we’ll display a toast message on button clicks telling us what button was clicked. We’ll finalize the functionality in the next tutorial.
This is what we will have at the end of this tutorial.
Video Tutorial
If you would rather watch a video then read all the way, you can check out this.
The video is a quick walkthrough. For detailed tutorial, please consider reading this article. If you choose to watch the video and find it useful, please give it a thumbsup and subscribe to the channel. Thank you. Lets continue.
Alright, now open the MainActivity.kt file. It looks something like this:
package com.example.tictactoe
//bunch of import statements
import ...
class MainActivity : AppCompatActivity() {
//TODO() 1: declare class variables here
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//TODO() 2: initialize player 1 and player 2 textviews
//TODO() 3: initialize 3x3 buttons
//TODO() 5: initialize resetbutton
//TODO() 6: set reset button onclick listener
}
//TODO() 4: declare initButton() function to initialize and set onClickListener to each button in 3x3 array.
}
TO-DOs:
- Declare
class
variables - Initialize Player 1 and Player 2
TextViews
- Initialize 3×3 GameBoard
Buttons
- Define initButton() function
- Initialize Reset
Button
- Set Reset button
onClickListener
Note:
Please take a note of the TODO() comments in the above code block to know where the following code snippets go.
1. Declare Class Variables
We declare these variables here as we will be accessing them throught the MainActivity Class.
lateinit var buttons: Array<Array<Button>>
lateinit var textViewPlayer1: TextView
lateinit var textViewPlayer2: TextView
private var player1Turn: Boolean = true
private var roundCount: Int = 0
private var player1Points: Int = 0
private var player2Points: Int = 0
Lateinit
In Kotlin, you must initialize an object’s properties when declaring the object. This implies that when you obtain an instance of a class, you can immediately reference any of its accessible properties. The
https://developer.android.com/kotlin/common-patternsView
objects in aFragment
, however, aren’t ready to be inflated until callingFragment#onCreateView
, so you need a way to defer property initialization for aView
.
Basically, you want to use lateinit
when you have to declare a variable but you can’t initialize it then and there and can only initialize it later. Hence, the term lateinit
. In our case, we want to declare the View variables outside the onCreate()
function so that we can use them all over the MainActivity class. But the View Objects aren’t ready until the onCreate
has been called. So we declare them here and initialize them inside onCreate
.
Var v/s Val
Every variable in Kotlin must be declared.
We use var
when the variable we declare is going to change or be reassigned a value. Note that we have to use var
with lateinit
since we will need to initialize the lateinit
variables later i.e. reassign them a value.
We use val
when the variable we are declaring isn’t going to change and need to be initialized just once i.e. for Read-Only or immutable variables.
Visibility Modifier: Private
The variables declared with a private
visibility modifier are visible only inside the class (including all its members) where they are declared.
2. Initialize Player 1 and Player 2 textView variables
textViewPlayer1 = findViewById(R.id.player1TextView)
textViewPlayer2 = findViewById(R.id.player2TextView)
findViewById
returns a reference to an instance of View. And with R.id.player1TextView
, we are asking findViewById
to give us an Android Resource(R
) with an id
of player1TextView
.
2. Initialize 2D buttons array
buttons = Array(3){r->
Array(3){c->
initButton(r, c)
}
}
3. Define initButton() function
private fun initButton(r: Int, c: Int): Button {
val btn: Button =
findViewById(resources.getIdentifier("btn$r$c", "id", packageName))
btn.setOnClickListener{
Toast.makeText(
applicationContext,
"button $r$c clicked",
Toast.LENGTH_SHORT).show()
}
return btn
}
resources.getIndentifier()
returns a resource identifier for the given resource name. For more on this, check out this link.
4. Initialize Reset button
val btnReset: Button = findViewById(R.id.btnReset)
5. Set Reset button OnClickListener
btnReset.setOnClickListener{
Toast.makeText(
applicationContext,
"Reset game button clicked!",
Toast.LENGTH_SHORT).show()
}
Final Code
Finally, here is all the code put together.
package com.example.tictactoe
import android.graphics.drawable.Drawable
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
class MainActivity : AppCompatActivity() {
lateinit var buttons: Array<Array<Button>>
lateinit var textViewPlayer1: TextView
lateinit var textViewPlayer2: TextView
private var player1Turn: Boolean = true
private var roundCount: Int = 0
private var player1Points: Int = 0
private var player2Points: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textViewPlayer1 = findViewById(R.id.player1TextView)
textViewPlayer2 = findViewById(R.id.player2TextView)
buttons = Array(3){r->
Array(3){c->
initButton(r, c)
}
}
val btnReset: Button = findViewById(R.id.btnReset)
btnReset.setOnClickListener{
Toast.makeText(
applicationContext,
"Reset game button clicked!",
Toast.LENGTH_SHORT).show()
}
}
private fun initButton(r: Int, c: Int): Button {
val btn: Button =
findViewById(resources.getIdentifier("btn$r$c", "id", packageName))
btn.setOnClickListener{
Toast.makeText(
applicationContext,
"button $r$c clicked",
Toast.LENGTH_SHORT).show()
}
return btn
}
}
Alright. This was fun and all but in the next one, we’ll really get our hands dirty and turn all this clicking into a proper tic tac toe game. Let’s move on to part-4 of this series.
Pingback: Tic Tac Toe Android Kotlin Beginner Series- Part 4 | HiHardik