Replace activity_main.xml with the 3x3 grid
Replace the file content in app/src/main/res/layout/activity_main.xml with the grid below. Each button uses a tag in the form row,col and calls onCellClick.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="3"
android:rowCount="3">
<Button
android:id="@+id/button00"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="0,0"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button01"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="0,1"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button02"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="0,2"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button10"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="1,0"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button11"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="1,1"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button12"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="1,2"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button20"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="2,0"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button21"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="2,1"
android:onClick="onCellClick"
android:textSize="24sp" />
<Button
android:id="@+id/button22"
android:layout_width="100dp"
android:layout_height="100dp"
android:tag="2,2"
android:onClick="onCellClick"
android:textSize="24sp" />
</GridLayout>
</LinearLayout>
Update MainActivity.java to use the model
In app/src/main/java/com/example/tictacmenu/activities/MainActivity.java, remove the Edge-to-Edge setup, create the model, and handle cell clicks.
What this change is trying to achieve
Right now the game screen is just a layout. We want it to become a playable Tic-Tac-Toe screen that delegates all game rules to the external model. That means:
- The Activity owns a
TicTacToeModelinstance. - Every button click becomes a move request to the model.
- After each move, the UI updates to show the current player and resets the board if the game ends.
New events and how they are wired
onCellClick(View view)
- This method is called directly by the XML. Each grid
<Button>hasandroid:onClick="onCellClick", so Android calls this method when the user taps that button. - The method reads the
tag(like"0,1") to know which row/col the player selected. - It asks the model if the move is legal, then writes the current player symbol into the clicked button.
- If the model reports a win or tie, it shows a
Toastand resets the game state.
resetBoard()
- This helper clears the UI after a win/tie.
- It loops over the 9 button ids and resets their text to an empty string.
The wiring is purely XML-driven: the android:onClick attribute in activity_main.xml is what connects each button to onCellClick.
import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
-import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.graphics.Insets;
-import androidx.core.view.ViewCompat;
-import androidx.core.view.WindowInsetsCompat;
import com.example.tictacmenu.R;
+import com.example.tictacmenu.models.TicTacToeModel;
public class MainActivity extends AppCompatActivity {
+ private TicTacToeModel model;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
- ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
- Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
- v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
- return insets;
- });
+ model = new TicTacToeModel();
+ }
+
+ public void onCellClick(View view) {
+ Button button = (Button) view;
+ String tag = button.getTag().toString();
+ String[] position = tag.split(",");
+ int row = Integer.parseInt(position[0]);
+ int col = Integer.parseInt(position[1]);
+
+ if (model.isLegal(row, col)) {
+ model.makeMove(row, col);
+ button.setText(model.getCurrentPlayer());
+
+ if (model.checkWin()) {
+ model.changePlayer();
+ Toast.makeText(this, "Player " + model.getCurrentPlayer() + " wins!", Toast.LENGTH_SHORT).show();
+ model.resetGame();
+ resetBoard();
+ } else if (model.isTie()) {
+ Toast.makeText(this, "It's a tie!", Toast.LENGTH_SHORT).show();
+ model.resetGame();
+ resetBoard();
+ } else {
+ model.changePlayer();
+ }
+ }
+ }
+
+ private void resetBoard() {
+ int[] buttonIds = {
+ R.id.button00, R.id.button01, R.id.button02,
+ R.id.button10, R.id.button11, R.id.button12,
+ R.id.button20, R.id.button21, R.id.button22
+ };
+
+ for (int id : buttonIds) {
+ Button button = findViewById(id);
+ button.setText("");
+ }
}
}At the end of this step: the game screen uses the external model and the 3x3 grid is interactive. Commit if you are tracking steps.