0

This is just the continuation of this thread.

I am creating an android app quiz with different topics. So i have buttons for the topics and quizNum column in my database for Quiz1, Quiz2, Quiz3 and so on...

Here's my code for Quiz.java

public class Practice extends Activity implements OnClickListener{

//constants
public static final String QUIZNUM = "QUIZNUM";
public static final int Quiz1 = 1;
public static final int Quiz2 = 2;
public static final int Quiz3 = 3;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.practice);

    //Menu buttons
    Button quiz1 = (Button) findViewById(R.id.q1Btn);
    quiz1.setOnClickListener(this);

    Button quiz2 = (Button) findViewById(R.id.q2Btn);
    quiz2.setOnClickListener(this);

    Button quiz3 = (Button) findViewById(R.id.q3Btn);
    quiz3.setOnClickListener(this);

}



public void onClick(View v) {
    Intent i;

    List<Question> questions = getQuestionSetFromDb();

    switch (v.getId()){


    case R.id.q1Btn :

        //Initialize quiz with retrieved question set
        CurrentQuiz c = new CurrentQuiz();
        c.setQuestions(questions);
        c.setNumRounds(getNumQuestions());
        c.setQuizNum(getQuizNum());

        ((MLearningApp)getApplication()).setCurrentGame(c);  


        i = new Intent(this, QuestionActivity.class);
        startActivity(i);
        break;


    case R.id.q2Btn :


        CurrentQuiz c2 = new CurrentQuiz();
        c2.setQuestions(questions);
        c2.setNumRounds(getNumQuestions());
        c2.setQuizNum(getQuizNum());
        ((MLearningApp)getApplication()).setCurrentGame(c2);  


        i = new Intent(this, QuestionActivity.class);
        startActivity(i);
        break;

    case R.id.q3Btn :

        CurrentQuiz c3 = new CurrentQuiz();
        c3.setQuestions(questions);
        c3.setNumRounds(getNumQuestions());
        c3.setQuizNum(getQuizNum());
        ((MLearningApp)getApplication()).setCurrentGame(c3);  


        i = new Intent(this, QuestionActivity.class);
        startActivity(i);
        break;
    }
}


// Method that retrieves a random set of questions from db

private List<Question> getQuestionSetFromDb() throws Error {

    int quizNum = getQuizNum();
    int numQuestions = getNumQuestions();
    DBHelper myDbHelper = new DBHelper(this);
    try {
        myDbHelper.createDataBase();
    } catch (IOException ioe) {
        throw new Error("Unable to create database");
    }
    try {
        myDbHelper.openDataBase();
    }catch(SQLException sqle){
        throw sqle;
    }
    List<Question> questions = myDbHelper.getQuestionSet(quizNum, numQuestions);
    myDbHelper.close();
    return questions;
}


private int getQuizNum() {
    int qNum = Quiz1;
    return qNum;    
}



private int getNumQuestions() {
    int numRounds = 10;
    return numRounds;
}

And here's my query in DBHelper.java

public List<Question> getQuestionSet(int qNum, int numQ){
    List<Question> questionSet = new ArrayList<Question>();

    Cursor c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE qNum = " + qNum + " ORDER BY RANDOM() LIMIT " + numQ, null);

    while (c.moveToNext()){

        Question q = new Question();
        q.setQuestion(c.getString(2));
        q.setAnswer(c.getString(3));
        q.setOption1(c.getString(4));
        q.setOption2(c.getString(5));

        questionSet.add(q);
    }
    return questionSet;
}

The quiz buttons are now running but it only retrieves questions from quiz1 (qNum table in db, 1). I was thinking of putting a looping statement in getQuizNum() method but i dont have an idea for the needed codes

Community
  • 1
  • 1
Kaitlin Reyes
  • 71
  • 1
  • 8

2 Answers2

0

The quiz buttons are now running but it only retrieves questions from quiz1

This is because you use getQuizNum() method to obtain which quiz to query:

private List<Question> getQuestionSetFromDb() throws Error {
    int quizNum = getQuizNum();
    //rest of the code...
}

And by looking at the implementation of getQuizNum(), you always return 1:

public static final int Quiz1 = 1;
//...
private int getQuizNum() {
    int qNum = Quiz1;
    return qNum;    
}

Change the code in getQuizNum to return one of the available results. Use a Random value, for example:

public static final int MAX_QUIZ_QUANTITY = 3;

private int getQuizNum() {
    Random r = new Random();
    return r.nextInt(MAX_QUIZ_QUANTITY) + 1;
}

I misunderstood the initial question but the problem remains the same. You should provide a different instance that implements OnClickListener interface for your quiz buttons. An alternative would be to move the code to implement onClick method into an inner class, thus removing the repeated code and making it reusable for different buttons:

//removed the implementation of OnClickListener from the class
//and moved into an inner class
//usually, your Activity doesn't implement OnClickListener unless there's a single button
public class Practice extends Activity {

    //constants
    public static final String QUIZNUM = "QUIZNUM";
    public static final int Quiz1 = 1;
    public static final int Quiz2 = 2;
    public static final int Quiz3 = 3;
    public static final int NUMBER_OF_QUESTIONS = 10;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.practice);

        //Menu buttons
        Button quiz1 = (Button) findViewById(R.id.q1Btn);
        quiz1.setOnClickListener(new PracticeButton(Quiz1, NUMBER_OF_QUESTIONS));

        Button quiz2 = (Button) findViewById(R.id.q2Btn);
        quiz2.setOnClickListener(new PracticeButton(Quiz2, NUMBER_OF_QUESTIONS));

        Button quiz3 = (Button) findViewById(R.id.q3Btn);
        quiz3.setOnClickListener(new PracticeButton(Quiz3, NUMBER_OF_QUESTIONS));
    }

    //inner class that provides the common functionality for the buttons
    class PracticeButton implements OnClickListener {

        //declaring fields in the inner class to provide flexibility
        //think of them as the necessary external parameters
        //for the functionality of the button
        int quizNumber;
        int numQuestions;
        //stating that the consumer of this class must provide the
        //parameters for the functionality of the button
        public PracticeButton(int quizNum, int numQuestions) {
            this.quizNum = quizNum;
            this.numQuestions = numQuestions;
        }

        //here you implement the onClick
        public void onClick(View v) {
            //the switch is not necessary anymore
            Intent i;
            List<Question> questions = getQuestionSetFromDb();
            CurrentQuiz c = new CurrentQuiz();
            c.setQuestions(questions);
            c.setNumRounds(numQuestions);
            c.setQuizNum(quizNum);
            ((MLearningApp)getApplication()).setCurrentGame(c);  
            i = new Intent(QuestionActivity.this, QuestionActivity.class);
            startActivity(i);
        }

        //replaced Error by Exception
        //Error should not be used, leave it to the JVM
        private List<Question> getQuestionSetFromDb() throws Exception {
            //moved these variables as fields
            //int quizNum = this.quizNumber;
            //int numQuestions = getNumQuestions();
            DBHelper myDbHelper = new DBHelper(QuestionActivity.this);
            try {
                myDbHelper.createDataBase();
            } catch (IOException ioe) {
                throw new Exception("Unable to create database");
            }
            try {
                myDbHelper.openDataBase();
            } catch (SQLException sqle) {
                throw sqle;
            }
            List<Question> questions = myDbHelper.getQuestionSet(quizNum, numQuestions);
            myDbHelper.close();
            return questions;
        }
    }
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Tried this but it randomizes quiz questions in different quizzes. It doesnt fit (qNum) 1 = Quiz1 button, (qNum) 2 = Quiz2 button, (qNum) 3 = Quiz3 button, what happens is that when i click quiz1 button, sometimes questions from quiz3 shows. When i click quiz2 btn, questions from q1 shows. It is because of the random right? but how would it get right? – Kaitlin Reyes Aug 11 '14 at 16:34
  • @KaitlinReyes answer updated with another approach to solve the problem. – Luiggi Mendoza Aug 11 '14 at 16:50
  • @KaitlinReyes sorry, my bad. Code fixed. – Luiggi Mendoza Aug 11 '14 at 17:28
  • It gives an error in QuestionActivity.this ( both in the intent and DBHelper) which says "no enclosing instance of type is accessible in scope" – Kaitlin Reyes Aug 11 '14 at 17:34
  • @KaitlinReyes now that's strange. I just tested the code and works for me. – Luiggi Mendoza Aug 11 '14 at 17:39
0

Let me show the relevant parts of the code:

switch (v.getId()){
case R.id.q1Btn :
    c.setQuizNum(getQuizNum());
    break;
case R.id.q2Btn :
    c2.setQuizNum(getQuizNum());
    break;
case R.id.q3Btn :
    c3.setQuizNum(getQuizNum());
    break;
}

getQuizNum() is useless; you want to set the actual number instead:

switch (v.getId()){
case R.id.q1Btn :
    c.setQuizNum(1);
    break;
case R.id.q2Btn :
    c2.setQuizNum(2);
    break;
case R.id.q3Btn :
    c3.setQuizNum(3);
    break;
}
CL.
  • 173,858
  • 17
  • 217
  • 259