Android Example

Quiz Example From T2J Program

The T2J program has a pretty good example of an app that will circulate through an array of questions and can collect the answers for whatever use you can come up with. It can be adapted to get questions from the Internet, a File or as it does in the example from resources. It doesn't do anything with the answers in this example but it could store them in a data base or send them to the Internet for tabulation as part of some bigger scheme. It does single and multiple line EditText answers and multiple choice RadioButton answers from which you can also make True/False answers.

Screen Dumps

Text Answer

Multiple Choice Answer

After you are done looking at the Java code you might like to download the program and let it make the example. You can see the rest of the code, export it to an Eclipse project and see it run. I called it App2 here but you can call it anything you want.

Check it out!

 

App2.java

package com.bandpsoftware.app2;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

public class App2 extends Activity {
    //These are just a few global variables and constants
    private static final int SHOW_QUIZ = 1;
    String[] qs = null;
    int qPointer = 0;
    private AlertDialog.Builder alert;
    Context mContext = null;

    @Override
    public void onCreate(Bundle icicle) {
        //The onCreate sets up the alert box that asks whether the user wants to 
        //quit or not. It also loads the questions from resources. It could get
        //the questions from anywhere, like the internet or a file.
        super.onCreate(icicle);
        setContentView(R.layout.main);
        mContext = this;
        qs = getResources().getStringArray(R.array.qanda);
        alert = new AlertDialog.Builder(this);
        alert.setIcon(android.R.drawable.ic_dialog_alert);
        alert.setPositiveButton(\"Go On\"new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //Restart if user chooses Go On button
                Intent in = new Intent(mContext, Quiz.class);
                in.putExtra(\"question\",qs[qPointer]);
                startActivityForResult(in, SHOW_QUIZ);
                }//onclick
            });//setPostiveButton
        alert.setNegativeButton(\"Quit \"new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //Quit if user chooses stop button
                finish();
                }//onclick
            });//setPostiveButton 

        }//oncreate

    @Override
    protected void onStart() {
        //This gives the main activity time to draw its screen before
        //the first question is displayed in the dialog screen
        super.onStart();
          Message m = startHandler.obtainMessage();
        startHandler.sendMessage(m);
        }//onstart
   
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SHOW_QUIZ)
            if (resultCode == Activity.RESULT_OK) {
                String s = data.getStringExtra(\"button\");
                if (s.equalsIgnoreCase(\"next\")) {
                    //Next question if user chooses Next button
                    qPointer++;
                    if (qPointer == qs.length) qPointer = 0;
                    Intent in = new Intent(mContext, Quiz.class);
                    in.putExtra(\"question\",qs[qPointer]);
                    startActivityForResult(in, SHOW_QUIZ);
                    s = data.getStringExtra(\"results\");
                    Toast.makeText(this,\"Answer: \"+s, Toast.LENGTH_SHORT).show();
                    }//next
                    else {
                        //Back to previous question if user presses the Back button
                        qPointer--;
                        if (qPointer < 0) qPointer = qs.length;
                        Intent in = new Intent(mContext, Quiz.class);
                        in.putExtra(\"question\",qs[qPointer]);
                        startActivityForResult(in, SHOW_QUIZ);
                        Toast.makeText(this,\"Back\", Toast.LENGTH_SHORT).show();
                        }//back
                
                }//if result_ok
                else {
                    //User has chosen Stop button. Ask if they want to quit.
                    alert.setTitle(\"Surveyor\");
                    alert.setMessage(\"Do You Want To Quit?\");
                    alert.show();
                    }//not ok
        }//onactivityresult

    Handler startHandler = new Handler() {
        //This calls the first question or where ever the qPointer is
        public void handleMessage(Message msg) {
            Intent in = new Intent(mContext, Quiz.class);
            in.putExtra(\"question\",qs[qPointer]);
            startActivityForResult(in, SHOW_QUIZ);
            }//handlemessge
        };//handler   
    
//TODO: Fill In Methods Etc.
}
//class

Quiz.java

package com.bandpsoftware.app2;

import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;

//Example Questions
//id,type,additional data,question,if multiple choice -answers
//Multiple Choice Type:0 Data:Number of answers
//Text Question   Type:1 Data:Max Lines
//Number, etc.    Type:n Data:x
//0001,0,3,Which Side of the Road Do Americans Drive on?,A. Left,B. Right,C. Either One

//The class appears in a dialog if we add this to the manifest:
//android:theme=\"@android:style/Theme.Dialog\"
//Which we did!

public class Quiz extends Activity {
    TextView question_String;
    public RadioGroup rg;
    public Vector fields;
    public int qType = 0;
    public int n = 0;
    public int i = 0;
    public Button btn;
    public Button btn2;
    
    String[] qQuestion = null;
    String sample = \"\";
    
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        
        //We don\'t want the dialog title for this
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        //If anything goes wrong return canceled result
        setResult(RESULT_CANCELED);

        Intent startingIntent = getIntent();
        if(startingIntent == null) {
            Log.e(\"RADIO\",\"No Intent?\");
            finish();
            return;
            }//if
        try {
            sample = startingIntent.getStringExtra(\"question\");
            }//try 
            catch (Exception e) {
                Log.e(\"RADIO\",\"No Question?\");
                finish();
                }//catched
 
        //Parse the question and make up new array of view items
        //for this question dialog    
        this.fields = new Vector();
        qQuestion = sample.split(\",\");
        //Type is stored in element 1
        qType = Integer.parseInt(qQuestion[1]);
        
        //Do the whole thing on a scroller in case it needs to scroll.
        //Scroller can only have one child so make it a linear layout.
        ScrollView sv = new ScrollView(this);
        final LinearLayout ll = new LinearLayout(this);
        sv.addView(ll);
        ll.setOrientation(android.widget.LinearLayout.VERTICAL);
        ll.setBackgroundColor(Color.BLACK);
        
        //This works for most phones may need revised for tablets
        ll.setMinimumWidth(300);
        
        //Add the question text to the layout. Put it in the first
        //field element.
        QField tempField =  new QField();       
        tempField.setName(\"question\");
        tempField.setLabel(qQuestion[3]);
        fields.add(tempField);
        fields.elementAt(0).obj = new QText(this, fields.elementAt(0).getLabel());
        ll.addView((View) fields.elementAt(0).obj);
        
        //Determine question type and setup appropriately
        switch (qType) {                      
        case 0://Multiple Choice
            //Setup the radio group layout. Use number of choices in third 
            //element of question strings
            n = Integer.parseInt(qQuestion[2].toString());
            i = 1;
            rg = new RadioGroup(this);
            rg.setLayoutParams(new LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,1.0f));
            //Add each answer choice to the group
            int j = n;
            while (j>0) {
                tempField.setName(\"radio_\"+i);
                tempField.setLabel(qQuestion[i+3]);
                fields.add(tempField);
                fields.elementAt(i).obj = new QRadio(this, qQuestion[i+3],(i==1),i);
                rg.addView((View) fields.elementAt(i).obj);
                i++; j--;
                }//while
            //Add the radio group to the overall linear layout
            ll.addView((View) rg);
            break;//multiplechoice
        case 1://Text Entry
            //We use n for the max lines in the QEdit class this time.
            //Text entry always put in the second fields element.
            n = Integer.parseInt(qQuestion[2].toString());
               tempField.setName(\"edit_1\");
            tempField.setLabel(\"\");
            fields.add(tempField);
            QEdit qe = new QEdit(this, n);
            qe.setOnEditorActionListener(mListener);
            fields.elementAt(1).obj = qe;
            ll.addView((View) fields.elementAt(1).obj);
            break;//textentry            

            //more types here
            
            }//switch

        //Setup the buttons layout
        final LinearLayout ll2 = new LinearLayout(this);
        ll.addView(ll2);
        ll2.setOrientation(android.widget.LinearLayout.HORIZONTAL);
        ll2.setWeightSum(2.0f);

        //Setup the buttons
        btn = new Button(this);             
        btn.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT,1.0f));
        ll2.addView(btn);
        btn.setText(\"Stop\");
        btn.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                //Handle the Stop button. Return canceled result
                finish();
                }//onclick     
            });//onclicklistener
        
        btn2 = new Button(this);            //This one returns its values
        btn2.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT,1.0f));
        ll2.addView(btn2);
        btn2.setText(\"Next\");
        btn2.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                //Handle the Done button. Return the question id,button name and answer
                   Intent in = new Intent();
                String s = \"\";
                   in.putExtra(\"id\", qQuestion[0]);
                   in.putExtra(\"button\", \"next\");
                   setResult(RESULT_OK,in);
                switch (qType) {
                case 0://Multiple Choice
                    //Return first character of selected answer
                    int id = rg.getCheckedRadioButtonId();
                    if (id>0) {
                           s = qQuestion[id+3].substring(0,1);
                              setResult(RESULT_OK,in);
                        }//if
                    in.putExtra(\"results\", s);
                    finish();
                    break;//multiplechoice
                case 1://Text Entry
                    //Return text that was entered
                    QEdit qe = (QEdit)fields.elementAt(1).obj;
                    s = qe.getText().toString();
                    in.putExtra(\"results\", s);
                    setResult(RESULT_OK,in);
                       finish();
                    break;//textentry
                    
                //more types here
                
                }//switch
                
                
                }//onclick
            } );
        
        //Assign this view to the dialogs window
        setContentView(sv);
        //Turned the title off up above but here\'s how to set it
        setTitle(\"Quiz\");
    
        }//oncreate
    
    @Override
    public void onBackPressed() {
        //Intercept the Back button. Return the question id and button name
        Intent in = new Intent();
        String s = \"\";
           in.putExtra(\"id\", qQuestion[0]);
           in.putExtra(\"button\", \"back\");
           setResult(RESULT_OK,in);
        in.putExtra(\"results\", \"\");
        finish();
        return;
        }//onbackpressed
 
    private TextView.OnEditorActionListener mListener =
        new TextView.OnEditorActionListener() {
        public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
            boolean b = (actionId == EditorInfo.IME_ACTION_DONE);
            if (n > 1) b = (actionId == EditorInfo.IME_NULL);     

            if (b) {                
                   Intent in = new Intent();
                String s = \"\";
                   in.putExtra(\"id\", qQuestion[0]);
                   in.putExtra(\"button\", \"next\");
                   setResult(RESULT_OK,in);
                QEdit qe = (QEdit)fields.elementAt(1).obj;
                s = qe.getText().toString();
                in.putExtra(\"results\", s);
                setResult(RESULT_OK,in);
                finish();
                }//return key  
            return true;     
        }
    };
    
//TODO: Fill In Methods Etc.
}//class
 
                     

QField.java

package com.bandpsoftware.app2;

public class QField {
    String name;           //We didn't use all of these fields.
    String label;
    String type;
    boolean required;
    String options;
    Object obj;            //Holds the view object for each item shown in the dialog
    
    
    //These methods get and set variables in the QField class
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLabel() {
        return label;
    }
    public void setLabel(String label) {
        this.label = label;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public boolean isRequired() {
        return required;
    }
    public void setRequired(boolean required) {
        this.required = required;
    }
    public String getOptions() {
        return options;
    }
    public void setOptions(String options) {
        this.options = options;
    }
}//class
 

QText.java

package com.bandpsoftware.app2;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;

public class QText extends LinearLayout {
    
    TextView label;
    //May need to revisit this one.
    public QText(Context context,String labelText) {
        super(context);
        label = new TextView(context);
        label.setTypeface(Typeface.MONOSPACE);
        label.setText(labelText);
        label.setTextColor(Color.WHITE);
        label.setPadding(5, 5, 5, 10);
        this.addView(label);
        }//constructor 

}//class
                                  

QEdit.java

package com.bandpsoftware.app2;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout.LayoutParams;

//This class is a text entry item for the quiz dialog
public class QEdit extends EditText {

    public QEdit(Context context, int lines) {
        super(context);
        this.setTypeface(Typeface.MONOSPACE);
        this.setText(\"\");
        this.setTextColor(Color.BLACK);
        this.setPadding(15, 5, 15, 5);
        this.setLayoutParams(new LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT,1.0f));
        this.setMaxLines(lines);
        //If lines is 1 we set it up for just a single line of text
        //otherwise it is wide open for a doctorial thesis.
        if (lines == 1) this.setSingleLine();
        }//constructor

}//class
                                  

QRadio.java

package com.bandpsoftware.app2;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.LinearLayout.LayoutParams;

//This sets up one radio button for addition to a radiogroup
//on the quiz dialog.
public class QRadio extends RadioButton {

    public QRadio(Context context, String labelText, boolean dsel, int id) {
        super(context);
        this.setTypeface(Typeface.MONOSPACE);
        this.setText(labelText);
        this.setTextColor(Color.WHITE);
        //this.setPadding(15, 5, 5, 5);
        this.setChecked(dsel);
        this.setLayoutParams(new LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,1.0f));
        //Usually this is the order in which they were read from the question
        this.setId(id);
        }//constructor
    
}//class