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
|
|
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