In this chapter, we will develop game logic in the GameActivity class, which assumes the role of controller in the MVC pattern. This controller:
Retrieves a question from the model, then presents it to the player with four possible answers.
Receives the player's response, verifies its accuracy, and displays the status (correct or incorrect answer).
Keeps track of the player's score.
Presents the score to the player at the end of the game.
Here's a preview of TopQuiz (just press "play"):
Let's turn our focus first to presenting a question and reacting to the user's answer.
Implement the Game Logic
Present a Question
We will retrieve a question from the data model using the getQuestion()
method of the QuestionBank class. To update the display, we will create a dedicated method that we can call whenever we need to present a new question. This method will take an instance of Question as a parameter then populate the display with its values. The method signature will look like this:
private void displayQuestion(final Question question) {
// Set the text for the question text view and the four buttons
}
The comment gives you a good indication of what you need to do next, so fill the method with the necessary logic.
Selecting an Answer
When the player chooses an answer, we have to intercept their button click. As we saw earlier, that requires us to add a listener to each button by implementing the View.OnClickListener
interface. And we could do that by writing the following for each button:
mAnswerButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Handle click on the first button
}
});
This would work well, but would result in excessive code duplication (four implementations total). Duplicating code comes at a cost: increasing the app size, requiring more processing, increasing maintenance costs...and think of your poor copy/pasting hand!
Instead of creating an anonymous class that implements View.OnClickListener
, we will have GameActivity
implement this interface. This allows us to define onClick()
but once. Begin by amending GameActivity's class declaration:
public class GameActivity extends AppCompatActivity implements View.OnClickListener
Android Studio underlined this declaration in red and that's because Android Studio detected that you have not implemented all the methods for the interface. To automatically retrieve the list of required methods and generate their corresponding signatures, press ALT + Insert on Windows or ⌘ + N on macOS, and select Implement Methods. You can also type CTRL + I.
In the onCreate()
method, set the GameActivity as the listener for all click events:
// Use the same listener for all four buttons.
mAnswerButton1.setOnClickListener(this);
mAnswerButton2.setOnClickListener(this);
mAnswerButton3.setOnClickListener(this);
mAnswerButton4.setOnClickListener(this);
The onClick()
method will now be invoked whenever the user clicks one of the four answer buttons.
But we need to distinguish which button the player actually presses. To do this, we will use View's setTag() method, and assign a different identifier to each button:
// Use the tag property to 'name' the buttons
mAnswerButton1.setTag(0);
mAnswerButton2.setTag(1);
mAnswerButton3.setTag(2);
mAnswerButton4.setTag(3);
Verify the Response
In the onClick()
method, the only input parameter is a View object. This View corresponds to one of the four available buttons. Therefore, call getTag()
on the View to determine which button the user clicked.
We previously defined the correct answer index in our data model. Go ahead and implement the logic to determine whether the chosen answer is accurate.
Present the Result
As you saw in the video, when the user selects a response, we display a message at the bottom of the screen. This message appears for a short time and then disappears automatically: otherwise known as a Toast. We can construct a Toast object by calling the static method, makeText()
. This method requires three parameters:
The application Context (usually the Activity itself).
The text to display.
How long to display it, in milliseconds.
The Toast class provides two predefined times: LENGTH_SHORT and LENGTH_LONG, corresponding to 2 seconds and 3.5 seconds, respectively. You can also set the duration by using the setDuration()
method on the Toast object.
Once you've constructed the Toast object, you must call the show()
method on the instance to display it. And you can chain calls to save precious lines:
Toast.makeText(this, "Correct!", Toast.LENGTH_SHORT).show();
Let's Recap!
Don’t forget to refactor your code. If you find yourself writing the same code over and over, it might be a good idea to break it down.
You can use the Toast API and invoke the
Toast.makeText().show()
method to display a temporary pop-up at the bottom of the screen.
Now you know how to implement an MVC architecture by querying the model to retrieve information and presenting it to the user. You almost have a functional app! In the next chapter, you’ll learn how to manage the player’s score.