Android Question Quiz App Radio Button

aeric

Expert
Licensed User
Longtime User
I would use panel inside CustomListView to do it, as I already done in my B4XQuiz.
With panel, I can create a square shape and set the corner radius 50% of the width/height. It becomes round. Set the border width to thicker if you like. That is how I did in my Todo List app. With panel as B4XView, I can change the color of the border using code.

There are also other custom views in B4X such as B4XRadioButton but I never use it and may not easy to customize.



1635358131345-png.121049
 
Last edited:
Upvote 0

zed

Active Member
Licensed User
Try this

B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
    SetColorTintList(RadioButton1,Colors.RGB(160,82,45),Colors.RGB(160,82,45),Colors.Gray)
End Sub

Sub SetColorTintList(RB As RadioButton,Checked As Int,Enabled As Int,Disabled As Int)

    Dim States(3,1) As Int
    States(0,0) = 16842912   'Checked
    States(1,0) = 16842910    'Enabled
    States(2,0) = -16842910 'Disabled

    Dim Color(3) As Int = Array As Int(Checked,Enabled,Disabled)

    Dim CSL As JavaObject
    CSL.InitializeNewInstance("android.content.res.ColorStateList",Array As Object(States,Color))
    Dim CB1 As JavaObject = RB
    CB1.RunMethod("setButtonTintList",Array As Object(CSL))

End Sub
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Only the good answer will change color to green.
An easy solution or addition to your solution is to use the Toast color to change the color depending on the answer:
B4X:
Dim userSelected As Int
    If rb1.Checked Then userSelected = 1
    If rb2.Checked Then userSelected = 2
    If rb3.Checked Then userSelected = 3

    If userSelected = GoodAnswer Then
        score = score+1
        Toast.Show($"You win [b]Score : ${score} points[/b]"$)
        Toast.pnl.Color =xui.Color_Green   'add this
    Else
        Toast.Show($"You lost : [b]Score : ${score} points[/b]"$)
        Toast.pnl.Color =xui.Color_Red    'add this
    End If
The question with changing the radio button color to green or red is: When do you change its color, when you check it or when you click the btCheck_Click to record your choice. In either case you are moving to the next question, so changing their color for a fraction of a second may not be very useful.. But changing the Toast color, not only tells you if you made the right choice, but also shows you the color, so you immediately know whether your answer is good or wrong without even having to read the toast text.
If your code is different from what was given to you, then you need to post it so one can see how your question needs to be addressed.
 
  • Like
Reactions: zed
Upvote 0

holyraf

Member
An easy solution or addition to your solution is to use the Toast color to change the color depending on the answer:
B4X:
Dim userSelected As Int
    If rb1.Checked Then userSelected = 1
    If rb2.Checked Then userSelected = 2
    If rb3.Checked Then userSelected = 3

    If userSelected = GoodAnswer Then
        score = score+1
        Toast.Show($"You win [b]Score : ${score} points[/b]"$)
        Toast.pnl.Color =xui.Color_Green   'add this
    Else
        Toast.Show($"You lost : [b]Score : ${score} points[/b]"$)
        Toast.pnl.Color =xui.Color_Red    'add this
    End If
The question with changing the radio button color to green or red is: When do you change its color, when you check it or when you click the btCheck_Click to record your choice. In either case you are moving to the next question, so changing their color for a fraction of a second may not be very useful.. But changing the Toast color, not only tells you if you made the right choice, but also shows you the color, so you immediately know whether your answer is good or wrong without even having to read the toast text.
If your code is different from what was given to you, then you need to post it so one can see how your question needs to be addressed.
I still want to show the changing of color before proceeding to the next question. I have a button for that. But yeah I can easily change the Radio Button Color through that code above. But how can I change the other Radio Buttons to Red? I have four (4) btw. Example:


I clicked/pressed the Correct Answer then it's corresponding Radio Button will change to green. And then the other three will change to Red.
Other example is when I pressed the Wrong Answer. The Radio Button with Correct Answer will change to Green, and the rest will change to Red.

I'm sorry, I'm sure this is simple to most of you guys. But I'm new to the B4A and I'm stuck at this. I need help. :(

Thank you!

This is my Current Code:

B4X:
Private Sub btnCheck_Click
    '    check
    Dim userSelected As Int
    If rbA1.Checked Then userSelected = 1
    If rbA2.Checked Then userSelected = 2
    If rbA3.Checked Then userSelected = 3
    If rbA4.Checked Then userSelected = 4

    If userSelected = GoodAnswer Then
        score = score+1
        ToastMessageShow($"You win [b]Score : ${score} points[/b]"$, True)
    Else
        ToastMessageShow($"You lost : [b]Score : ${score} points[/b]"$,True)
    End If
End Sub
 
Last edited:
Upvote 0

aeric

Expert
Licensed User
Longtime User
The Radio Button with Correct Answer will change to Green, and the rest will change to Red.
I don't think other wrong answers should change to Red.
This is quite annoying because I would think I didn't selected the other answers. Why punish me with so many Red marks?

May be I will do like this.

Eg. Let say there are 4 options, A, B, C, D and the answer is B.

If I choose B, the radio button will turn to Blue. When I press the "Check" button, then B radio button will turn to Green, others still remain Gray.

If I choose A, the radio button will turn to Blue. When I press the "Check" button, then B radio button will have an outer circle with Red color, others still remain Gray except A still remain Blue. Like this, I still know which wrong answer I have chosen.

Then the "Check" button change text to "Next" and change to different color.

Another way is I will set the background of the answer with a lighter shade of color and darker border Green and Red to indicate Correct and Wrong answers.

Third way is change my selected answer to Red, others remain Gray if I got the wrong answer. The correct answer change to Green.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Make sure first to make all 3 radio buttons have the same event name called: rb. Also for the 1st button put its tag to be 1, for the 2nd put 2, for the 3rd put 3.

1685030112337.png


Then, add these 2 subs to your code:
B4X:
Sub rb_CheckedChange(Checked As Boolean)  'new sub
        For Each v As View In Root.GetAllViewsRecursive
            If v Is RadioButton Then
                Dim rr As RadioButton = v
                If GoodAnswer = rr.Tag  Then
                    rr.Color =xui.Color_Green
                Else
                    rr.Color =xui.Color_Red
                End If
                If rr.Tag <> Sender.As(RadioButton).Tag Then
                    rr.Color=xui.Color_white
                End If
            End If
        Next
End Sub

Sub ResetRadioButtonsColors  'new sub 
    For Each v As View In Root.GetAllViewsRecursive
        If v Is RadioButton Then
            Dim rr As RadioButton = v
            rr.Color=xui.Color_white
        End If
    Next
End Sub
Also to reset the original colors of the buttons, add the call to the sub Sub btCheck_Click like you see below:
Private Sub btCheck_Click
ResetRadioButtonsColors 'add this line to this sub
 
Upvote 0

zed

Active Member
Licensed User
Another variant keeping the colors of the radiobutton.

I know that in pnlRadioButton there are only RadioButton

For Each v As View In Root.GetAllViewsRecursive
B4X:
Sub rb_CheckedChange(Checked As Boolean)  'new sub
    For Each rb As RadioButton In pnlRadioButton.GetAllViewsRecursive
        If GoodAnswer = rb.Tag  Then
            SetColorTintList(rb,Colors.Green,Colors.Green,Colors.Gray)
        Else
            SetColorTintList(rb,Colors.Red,Colors.Red,Colors.Gray)
        End If
    Next
End Sub

Private Sub reset_radiobutton
    rb1.Checked = False
    rb2.Checked = False
    rb3.Checked = False
    
    For Each rb As RadioButton In pnlRadioButton.GetAllViewsRecursive
        SetColorTintList(rb,Colors.Gray,Colors.Gray,Colors.Gray)
    Next
    
End Sub

Sub SetColorTintList(RB As RadioButton,Checked As Int,Enabled As Int,Disabled As Int)

    Dim States(3,1) As Int
    States(0,0) = 16842912   'Checked
    States(1,0) = 16842910    'Enabled
    States(2,0) = -16842910 'Disabled

    Dim Color(3) As Int = Array As Int(Checked,Enabled,Disabled)

    Dim CSL As JavaObject
    CSL.InitializeNewInstance("android.content.res.ColorStateList",Array As Object(States,Color))
    Dim CB1 As JavaObject = RB
    CB1.RunMethod("setButtonTintList",Array As Object(CSL))

End Sub
 
Upvote 0

holyraf

Member
Hi guys! Thanks for the Code and Outputs. I managed to achieve the Color Changes, I also created a Countdown timer. But the Question Randomizer I implemented is no good. It's still repeating. Can you guys give me an idea/code on how to do randomized question without repeating and then end if all the questions are shown. Thanks guys!

At the moment, Here is my random code:


B4X:
Private Sub loadQuestion(n As Int)
    
    lblQ.Text =  $"Tanong ${n} / ${nbrQ}"$
    
    Dim RS As ResultSet = SQL1.ExecQuery("SELECT * FROM quiz_data where ID ="&n&" ORDER BY Random()")
    
    RS.NextRow
    myQ = RS.GetString("Question").Trim
    myA1 = RS.GetString("Answer1").Trim
    myA2 = RS.GetString("Answer2").Trim
    myA3 = RS.GetString("Answer3").Trim
    myA4 = RS.GetString("Answer4").Trim
    GoodAnswer = RS.GetInt("Tag")
        
    lblQuestion.Text = myQ
    rbA1.Text = myA1
    rbA2.Text = myA2
    rbA3.Text = myA3
    rbA4.Text = myA4

End Sub
 
  • Like
Reactions: omo
Upvote 0

zed

Active Member
Licensed User
The sql query is not correct.
Dim RS As ResultSet = SQL1.ExecQuery("SELECT * FROM quiz_data where ID ="&n&" ORDER BY Random()")

SQLite:
Dim RS As ResultSet = SQL1.ExecQuery("SELECT * FROM quiz_data where ORDER BY Random()")

Initially, it was just a code snippet.
Now, if it's a complete application that needs to be done, it would be easier to do as @aeric suggests.
Put all questions in a global list

Here is the code change. Complete project in the zip


You have to add a "view" field to the db and set it to 0

B4X:
'selection of a random question that has not yet been asked. - view=0
Dim RS As ResultSet = SQL1.ExecQuery("SELECT * FROM table_quiz where view = 0 ORDER BY Random()")
    
'if there are no more questions
If RS.RowCount = 0 Then
    Toast.Show($"[b]All the questions have already been asked[/b]"$)
    Return
End If

When the question is displayed

B4X:
'the question has already been answered.
'I set 'view' to 1 so as not to repeat the question a second time
SQL1.ExecNonQuery("UPDATE table_quiz Set view = 1  WHERE id_question = " & myId & "")
 

Attachments

  • quiz.zip
    12.2 KB · Views: 165
Upvote 0
Top