33import android .content .Context ;
44import android .content .Intent ;
55import android .database .Cursor ;
6+ import android .graphics .Color ;
67import android .hardware .Sensor ;
78import android .hardware .SensorEvent ;
89import android .hardware .SensorEventListener ;
1112import android .view .View ;
1213import android .widget .Button ;
1314import android .widget .ImageButton ;
15+ import android .widget .SeekBar ;
1416import android .widget .TextView ;
1517import android .widget .Toast ;
1618
@@ -36,8 +38,9 @@ public class QuizActivity extends AppCompatActivity implements SensorEventListen
3638 private TextView questionText ;
3739 private Button [] textButtons = new Button [4 ];
3840 private ImageButton [] imageButtons = new ImageButton [4 ];
39- private double allQuestionPointTotal = 0 ; // used for calculating percentages in the results
41+ private double allQuestionPointTotal = 0 ;
4042 private int skipCount = 0 ;
43+ private boolean sliderTouched = false ; // check if the slider was touched
4144
4245 @ Override
4346 protected void onCreate (Bundle savedInstanceState ) {
@@ -47,23 +50,23 @@ protected void onCreate(Bundle savedInstanceState) {
4750
4851 questionText = binding .questionText ;
4952
50- //For the text based answers
5153 textButtons [0 ] = binding .optionA ;
5254 textButtons [1 ] = binding .optionB ;
5355 textButtons [2 ] = binding .optionC ;
5456 textButtons [3 ] = binding .optionD ;
5557
56- //For the image based answers
5758 imageButtons [0 ] = binding .imageAnswerA ;
5859 imageButtons [1 ] = binding .imageAnswerB ;
5960 imageButtons [2 ] = binding .imageAnswerC ;
6061 imageButtons [3 ] = binding .imageAnswerD ;
6162
63+ questionList = new ArrayList <>();
64+ questionList .add (new Question (999 , "How much do you enjoy large social gatherings?" , "slider" ));
65+
6266 QuizDB db = new QuizDB (this );
6367 Cursor cursor = db .getRandomQuestions (10 );
64- questionList = new ArrayList <>();
6568
66- if (cursor .moveToFirst ()) {
69+ if (cursor .moveToFirst ()) {
6770 do {
6871 int questionId = cursor .getInt (cursor .getColumnIndexOrThrow ("question_id" ));
6972 String questionText = cursor .getString (cursor .getColumnIndexOrThrow ("question_content" ));
@@ -74,8 +77,9 @@ protected void onCreate(Bundle savedInstanceState) {
7477 cursor .close ();
7578
7679 loadQuestion ();
80+
7781 sensorManager = (SensorManager ) getSystemService (Context .SENSOR_SERVICE );
78- if (sensorManager != null ) {
82+ if (sensorManager != null ) {
7983 accelerometer = sensorManager .getDefaultSensor (Sensor .TYPE_ACCELEROMETER );
8084 }
8185 }
@@ -100,19 +104,35 @@ private void loadQuestion() {
100104 int totalQuestions = questionList .size ();
101105 int percent = (int ) ((float ) currentQuestionIndex / totalQuestions * 100 );
102106
103- //Progress bar
104107 binding .progressBar .setMax (questionList .size ());
105108 binding .progressBar .setProgress (currentQuestionIndex , true );
106109 binding .progressBarText .setText (getString (R .string .progressBarPercent , percent ));
107110
111+ binding .textAnswerLayout .setVisibility (View .GONE );
112+ binding .imageAnswerLayout .setVisibility (View .GONE );
113+ binding .sliderAnswerLayout .setVisibility (View .GONE );
114+
108115 Question q = questionList .get (currentQuestionIndex );
109116 questionText .setText (q .questionContent );
110117
118+ if (q .questionType .equalsIgnoreCase ("image" )) {
119+ binding .imageAnswerLayout .setVisibility (View .VISIBLE );
120+ loadImageAnswers (q );
121+ } else if (q .questionType .equalsIgnoreCase ("slider" )) {
122+ binding .sliderAnswerLayout .setVisibility (View .VISIBLE );
123+ setupSlider ();
124+ } else {
125+ binding .textAnswerLayout .setVisibility (View .VISIBLE );
126+ loadTextAnswers (q );
127+ }
128+ }
129+
130+ private void loadImageAnswers (Question q ) {
111131 QuizDB db = new QuizDB (this );
112132 Cursor cursor = db .getAnswersForQuestion (q .questionId );
113133 currentAnswers = new ArrayList <>();
114134
115- if (cursor .moveToFirst ()) {
135+ if (cursor .moveToFirst ()) {
116136 do {
117137 int answerId = cursor .getInt (cursor .getColumnIndexOrThrow ("answer_id" ));
118138 int correspondingQuestionId = cursor .getInt (cursor .getColumnIndexOrThrow ("corresponding_question_id" ));
@@ -126,85 +146,169 @@ private void loadQuestion() {
126146 }
127147 cursor .close ();
128148
129- //Shuffling the order of the answers
130149 Collections .shuffle (currentAnswers );
131150
132- if (q .questionType .equalsIgnoreCase ("image" )) {
133- // Question with image answers
134- binding .textAnswerLayout .setVisibility (View .GONE );
135- binding .imageAnswerLayout .setVisibility (View .VISIBLE );
151+ for (int i = 0 ; i < 4 ; i ++) {
152+ int id = getResources ().getIdentifier (currentAnswers .get (i ).answerContent , "drawable" , getPackageName ());
153+ imageButtons [i ].setImageResource (id );
154+ final int index = i ;
155+ imageButtons [i ].setOnClickListener (v -> selectedAnswer (index ));
156+ }
157+ }
158+
159+ private void loadTextAnswers (Question q ) {
160+ QuizDB db = new QuizDB (this );
161+ Cursor cursor = db .getAnswersForQuestion (q .questionId );
162+ currentAnswers = new ArrayList <>();
163+
164+ if (cursor .moveToFirst ()) {
165+ do {
166+ int answerId = cursor .getInt (cursor .getColumnIndexOrThrow ("answer_id" ));
167+ int correspondingQuestionId = cursor .getInt (cursor .getColumnIndexOrThrow ("corresponding_question_id" ));
168+ String answerContent = cursor .getString (cursor .getColumnIndexOrThrow ("answer_content" ));
169+ String primaryPersonality = cursor .getString (cursor .getColumnIndexOrThrow ("primary_personality" ));
170+ String secondaryPersonality = cursor .getString (cursor .getColumnIndexOrThrow ("secondary_personality" ));
171+ String tertiaryPersonality = cursor .getString (cursor .getColumnIndexOrThrow ("tertiary_personality" ));
172+ int answerPointTotal = cursor .getInt (cursor .getColumnIndexOrThrow ("answer_point_total" ));
173+ currentAnswers .add (new Answer (answerId , correspondingQuestionId , answerContent , primaryPersonality , secondaryPersonality , tertiaryPersonality , answerPointTotal ));
174+ } while (cursor .moveToNext ());
175+ }
176+ cursor .close ();
177+
178+ Collections .shuffle (currentAnswers );
179+
180+ for (int i = 0 ; i < 4 ; i ++) {
181+ textButtons [i ].setText (currentAnswers .get (i ).answerContent );
182+ final int index = i ;
183+ textButtons [i ].setOnClickListener (v -> selectedAnswer (index ));
184+ }
185+ }
136186
137- for (int i = 0 ; i < 4 ; i ++) {
138- int id = getResources ().getIdentifier (currentAnswers .get (i ).answerContent , "drawable" , getPackageName ());
139- imageButtons [i ].setImageResource (id );
187+ private void setupSlider () {
188+ sliderTouched = false ;
189+ binding .sliderSeekBar .setProgress (50 );
190+ binding .sliderLabel .setText ("Move the slider" );
140191
141- // effectively final index to use lambda expression
142- final int index = i ;
143- imageButtons [i ].setOnClickListener (v -> selectedAnswer (index ));
192+ binding .sliderSeekBar .setOnSeekBarChangeListener (new SeekBar .OnSeekBarChangeListener () {
193+ @ Override
194+ public void onProgressChanged (SeekBar seekBar , int progress , boolean fromUser ) {
195+ if (fromUser ) {
196+ sliderTouched = true ;
197+ }
198+
199+ if (progress <= 20 ) {
200+ binding .sliderLabel .setText ("Not much" );
201+ } else if (progress <= 60 ) {
202+ binding .sliderLabel .setText ("Neutral" );
203+ } else {
204+ binding .sliderLabel .setText ("A lot" );
205+ }
206+
207+ // Animate background color 🎨
208+ int startColor = 0xFF2196F3 ; // blue
209+ int midColor = 0xFF9C27B0 ; // purple
210+ int endColor = 0xFFF44336 ; // red
211+
212+ int newColor ;
213+ if (progress <= 50 ) {
214+ float fraction = progress / 50f ;
215+ newColor = blendColors (startColor , midColor , fraction );
216+ } else {
217+ float fraction = (progress - 50 ) / 50f ;
218+ newColor = blendColors (midColor , endColor , fraction );
219+ }
220+ binding .sliderAnswerLayout .setBackgroundColor (newColor );
144221 }
145- } else {
146- // Question with text answers
147- binding .textAnswerLayout .setVisibility (View .VISIBLE );
148- binding .imageAnswerLayout .setVisibility (View .GONE );
149222
150- for (int i = 0 ; i < 4 ; i ++) {
151- textButtons [i ].setText (currentAnswers .get (i ).answerContent );
223+ @ Override public void onStartTrackingTouch (SeekBar seekBar ) {}
224+ @ Override public void onStopTrackingTouch (SeekBar seekBar ) {}
225+ });
152226
153- // effectively final index to use lambda expression
154- final int index = i ;
155- textButtons [i ].setOnClickListener (v -> selectedAnswer (index ));
227+ binding .submitSliderButton .setOnClickListener (v -> {
228+ if (!sliderTouched ) {
229+ Toast .makeText (this , "Move the slider before hitting submit!!" , Toast .LENGTH_SHORT ).show ();
230+ return ;
156231 }
157- }
232+
233+ int progress = binding .sliderSeekBar .getProgress ();
234+ String selectedLevel ;
235+
236+ if (progress <= 20 ) {
237+ selectedLevel = "Not much" ;
238+ } else if (progress <= 60 ) {
239+ selectedLevel = "Neutral" ;
240+ } else {
241+ selectedLevel = "A lot" ;
242+ }
243+
244+ if (selectedLevel .equals ("Not much" )) {
245+ addPersonalityPoints ("introvert" , 10 );
246+ } else if (selectedLevel .equals ("Neutral" )) {
247+ addPersonalityPoints ("balanced" , 15 );
248+ } else {
249+ addPersonalityPoints ("extrovert" , 20 );
250+ }
251+
252+ moveToNextQuestion ();
253+ });
254+ }
255+
256+ private int blendColors (int color1 , int color2 , float ratio ) {
257+ final float inverseRatio = 1f - ratio ;
258+ float r = (color1 >> 16 & 0xff ) * inverseRatio + (color2 >> 16 & 0xff ) * ratio ;
259+ float g = (color1 >> 8 & 0xff ) * inverseRatio + (color2 >> 8 & 0xff ) * ratio ;
260+ float b = (color1 & 0xff ) * inverseRatio + (color2 & 0xff ) * ratio ;
261+ return 0xff << 24 | ((int ) r << 16 ) | ((int ) g << 8 ) | (int ) b ;
262+ }
263+
264+ private void addPersonalityPoints (String personality , int points ) {
265+ double current = scoreMap .getOrDefault (personality , 0.0 );
266+ scoreMap .put (personality , current + points );
267+ allQuestionPointTotal += points ;
158268 }
159269
160270 private void selectedAnswer (int index ) {
161271 Answer selectedAnswer = currentAnswers .get (index );
162272 int pointTotal = selectedAnswer .answerPointTotal ;
163- allQuestionPointTotal = allQuestionPointTotal + pointTotal ; // update allQuestionPointTotal with the pointTotal for this question
164-
165- int personalityTotal = 0 ; // the number of personalities this answer affects
166-
167- // will hold the current scores of the personality types this answer affects
168- double primaryScore = 0.0 ;
169- double secondaryScore = 0.0 ;
170- double tertiaryScore = 0.0 ;
273+ allQuestionPointTotal += pointTotal ;
171274
275+ int personalityTotal = 0 ;
276+ double primaryScore = 0.0 , secondaryScore = 0.0 , tertiaryScore = 0.0 ;
172277 double primaryPoints , secondaryPoints , tertiaryPoints ;
173278
174279 String primaryPersonality = selectedAnswer .primaryPersonality ;
175- if (primaryPersonality != null ) {
280+ if (primaryPersonality != null ) {
176281 primaryScore = scoreMap .getOrDefault (primaryPersonality , 0.0 );
177282 personalityTotal ++;
178283 }
179284
180285 String secondaryPersonality = selectedAnswer .secondaryPersonality ;
181- if (secondaryPersonality != null ) {
286+ if (secondaryPersonality != null ) {
182287 secondaryScore = scoreMap .getOrDefault (secondaryPersonality , 0.0 );
183288 personalityTotal ++;
184289 }
185290
186291 String tertiaryPersonality = selectedAnswer .tertiaryPersonality ;
187- if (tertiaryPersonality != null ) {
292+ if (tertiaryPersonality != null ) {
188293 tertiaryScore = scoreMap .getOrDefault (tertiaryPersonality , 0.0 );
189294 personalityTotal ++;
190295 }
191296
192- // Add points to each of the current scores depending on how many personalities the answer affects
193- switch (personalityTotal ) {
297+ switch (personalityTotal ) {
194298 case 1 :
195299 primaryPoints = pointTotal ;
196300 scoreMap .put (primaryPersonality , primaryScore + primaryPoints );
197301 break ;
198302 case 2 :
199- primaryPoints = pointTotal * 0.75 ;
200- secondaryPoints = pointTotal * 0.25 ;
303+ primaryPoints = pointTotal * 0.75f ;
304+ secondaryPoints = pointTotal * 0.25f ;
201305 scoreMap .put (primaryPersonality , primaryScore + primaryPoints );
202306 scoreMap .put (secondaryPersonality , secondaryScore + secondaryPoints );
203307 break ;
204308 case 3 :
205- primaryPoints = pointTotal * 0.65 ;
206- secondaryPoints = pointTotal * 0.25 ;
207- tertiaryPoints = pointTotal * 0.1 ;
309+ primaryPoints = pointTotal * 0.65f ;
310+ secondaryPoints = pointTotal * 0.25f ;
311+ tertiaryPoints = pointTotal * 0.1f ;
208312 scoreMap .put (primaryPersonality , primaryScore + primaryPoints );
209313 scoreMap .put (secondaryPersonality , secondaryScore + secondaryPoints );
210314 scoreMap .put (tertiaryPersonality , tertiaryScore + tertiaryPoints );
@@ -214,12 +318,8 @@ private void selectedAnswer(int index) {
214318 moveToNextQuestion ();
215319 }
216320
217- /**
218- * Determines whether to progress to the next question or show the result.
219- */
220321 private void moveToNextQuestion () {
221322 currentQuestionIndex ++;
222-
223323 if (currentQuestionIndex < questionList .size ()) {
224324 loadQuestion ();
225325 } else {
@@ -228,18 +328,15 @@ private void moveToNextQuestion() {
228328 }
229329
230330 private void showResult () {
231- // Sort scoreMap entries by score in descending order
232331 List <HashMap .Entry <String , Double >> sortedScores = new ArrayList <>(scoreMap .entrySet ());
233332 Collections .sort (sortedScores , (a , b ) -> Double .compare (b .getValue (), a .getValue ()));
234333
235334 String primaryPersonality = "Unknown" ;
236335 String secondaryPersonality = "Unknown" ;
237336 String tertiaryPersonality = "Unknown" ;
238- double primaryScore = 0 ;
239- double secondaryScore = 0 ;
240- double tertiaryScore = 0 ;
337+ double primaryScore = 0 , secondaryScore = 0 , tertiaryScore = 0 ;
241338
242- if (sortedScores .size () > 0 ) {
339+ if (! sortedScores .isEmpty () ) {
243340 primaryPersonality = sortedScores .get (0 ).getKey ();
244341 primaryScore = sortedScores .get (0 ).getValue ();
245342 }
@@ -252,7 +349,6 @@ private void showResult() {
252349 tertiaryScore = sortedScores .get (2 ).getValue ();
253350 }
254351
255- // Pass important info to ResultActivity
256352 Intent intent = new Intent (QuizActivity .this , ResultActivity .class );
257353 intent .putExtra ("PRIMARY_PERSONALITY" , primaryPersonality );
258354 intent .putExtra ("PRIMARY_PERSONALITY_SCORE" , primaryScore );
@@ -266,18 +362,18 @@ private void showResult() {
266362 }
267363
268364 @ Override
269- public void onSensorChanged (SensorEvent sensorEvent ) {
270- if (sensorEvent .sensor .getType () == Sensor .TYPE_ACCELEROMETER ) {
271- float x = sensorEvent .values [0 ];
272- float y = sensorEvent .values [1 ];
273- float z = sensorEvent .values [2 ];
365+ public void onSensorChanged (SensorEvent event ) {
366+ if (event .sensor .getType () == Sensor .TYPE_ACCELEROMETER ) {
367+ float x = event .values [0 ];
368+ float y = event .values [1 ];
369+ float z = event .values [2 ];
274370
275371 double acceleration = Math .sqrt (x * x + y * y + z * z );
276372 long currentTime = System .currentTimeMillis ();
277373
278374 if (acceleration > 15 && currentTime - lastShakeTime > 1000 ) {
279375 lastShakeTime = currentTime ;
280- if (skipCount < 2 ) {
376+ if (skipCount < 2 ) {
281377 moveToNextQuestion ();
282378 skipCount ++;
283379 Toast .makeText (this , "Question skipped!" , Toast .LENGTH_SHORT ).show ();
@@ -288,7 +384,5 @@ public void onSensorChanged(SensorEvent sensorEvent) {
288384 }
289385
290386 @ Override
291- public void onAccuracyChanged (Sensor sensor , int i ) {
292-
293- }
387+ public void onAccuracyChanged (Sensor sensor , int i ) {}
294388}
0 commit comments