BranchingChoiceExample
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical" | |
tools:context="com.example.choiceapp.MainActivity"> | |
<TextView | |
android:id="@+id/question_text" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:textAppearance="@style/TextAppearance.AppCompat.Large" | |
android:text="Hello World!"/> | |
<ListView | |
android:id="@+id/question_options" | |
android:layout_weight="8" | |
android:layout_width="match_parent" | |
android:layout_height="0dp"> | |
</ListView> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<Button | |
android:id="@+id/button_restart" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
android:text="Restart"/> | |
<Button | |
android:id="@+id/button_back" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
android:text="Back"/> | |
</LinearLayout> | |
</LinearLayout> |
package com.example.choiceapp; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.util.Log; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.Adapter; | |
import android.widget.AdapterView; | |
import android.widget.ArrayAdapter; | |
import android.widget.BaseAdapter; | |
import android.widget.Button; | |
import android.widget.ListAdapter; | |
import android.widget.ListView; | |
import android.widget.TextView; | |
import java.util.ArrayList; | |
import java.util.EnumSet; | |
public class MainActivity extends AppCompatActivity | |
{ | |
TextView mQuestionView; | |
ListView mOptionView; | |
QuestionAdapter mAdapter; | |
ListAdapter mAnswerAdapater; | |
Button mRestartButton; | |
Button mBackButton; | |
ArrayList<Question<?>> mAnsweredQuestions = new ArrayList<>(); | |
enum Age | |
{ | |
CHILD, | |
ADULT | |
} | |
enum Height | |
{ | |
SHORT, | |
NORMAL, | |
TALL | |
} | |
enum Occupation | |
{ | |
CHILD, | |
STUDENT, | |
WORKING, | |
JOBLESS | |
} | |
//Abstract, generic class. | |
//This class requires that another class extend it. | |
//the T represetns another class, in our case any of the Enums | |
//that provide us with the selectable options | |
abstract class Question<T> | |
{ | |
String mQuestion; | |
T[] mOptions; | |
Question mNext; | |
T Answer; | |
public Question(String question, T... options) | |
{ | |
mQuestion = question; | |
mOptions = options; | |
} | |
@Override | |
public String toString() | |
{ | |
return Answer.toString(); | |
} | |
public abstract Question getNext(int selectedOption); | |
} | |
/////////////// | |
// Age | |
/////////////// | |
class AgeQuestion extends Question<Age> | |
{ | |
public AgeQuestion(Age... options) | |
{ | |
super("Are you an adult?", options ); | |
} | |
@Override | |
public Question getNext(int selectedOption) | |
{ | |
Age option = mOptions[selectedOption]; | |
Answer = option; | |
if (option == Age.ADULT) | |
{ | |
//If adult, occuptation question will include these options | |
return new OccupationQuestion( Occupation.JOBLESS, | |
Occupation.STUDENT, | |
Occupation.WORKING ); | |
} | |
else | |
{ | |
//Otherwise just child, not that it matters. | |
return new OccupationQuestion( Occupation.CHILD ); | |
} | |
} | |
} | |
/////////////// | |
// Occuptation | |
/////////////// | |
class OccupationQuestion extends Question<Occupation> | |
{ | |
public OccupationQuestion(Occupation... options) | |
{ | |
super("What is your occuptation?", options ); | |
} | |
@Override | |
public Question getNext(int selectedOption) | |
{ | |
Occupation option = mOptions[selectedOption]; | |
this.Answer = option; | |
//Next question should contain all options regardless | |
return new HeightQuestion( Height.SHORT, | |
Height.NORMAL, | |
Height.TALL ); | |
} | |
} | |
/////////////// | |
// Height | |
/////////////// | |
class HeightQuestion extends Question<Height> | |
{ | |
public HeightQuestion(Height... options) | |
{ | |
super("What is your height?", options ); | |
} | |
@Override | |
public Question getNext(int selectedOption) | |
{ | |
Height option = mOptions[selectedOption]; | |
this.Answer = option; | |
//Last question, return null to indicate end. | |
return null; | |
} | |
} | |
private class QuestionAdapter extends BaseAdapter | |
{ | |
Question mQuestion; | |
QuestionAdapter(){}; | |
public void setQuestion(Question question) | |
{ | |
mQuestion = question; | |
notifyDataSetChanged(); | |
} | |
public Question getQuestion() | |
{ | |
return mQuestion; | |
} | |
@Override | |
public int getCount() | |
{ | |
if (mQuestion == null) | |
return 0; | |
return mQuestion.mOptions.length; | |
} | |
@Override | |
public Object getItem(int position) | |
{ | |
return mQuestion.mOptions[position]; | |
} | |
@Override | |
public long getItemId(int position) | |
{ | |
return 0; | |
} | |
@Override | |
public View getView(final int position, View convertView, ViewGroup parent) | |
{ | |
if (convertView == null) | |
convertView = new Button(parent.getContext()); | |
((Button)convertView).setText( mQuestion.mOptions[position].toString() ); //Just using toString of enum for simplciity | |
convertView.setOnClickListener(new View.OnClickListener() | |
{ | |
@Override | |
public void onClick(View v) | |
{ | |
Question question = mAdapter.getQuestion(); | |
mAnsweredQuestions.add( question ); | |
MainActivity.this.setupQuestion( question.getNext( position ) ); | |
} | |
}); | |
return convertView; | |
} | |
} | |
private void displayAnswers() | |
{ | |
String[] answers = new String[mAnsweredQuestions.size()]; | |
for (int i = 0; i < mAnsweredQuestions.size(); i++) | |
{ | |
answers[i] = mAnsweredQuestions.get(i).toString(); | |
} | |
mAnswerAdapater = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, answers); | |
mOptionView.setAdapter(mAnswerAdapater); | |
mBackButton.setEnabled(false); | |
} | |
private void setupQuestion( Question ques ) | |
{ | |
if (ques == null) | |
{ | |
//All done, display answers | |
displayAnswers(); | |
return; | |
} | |
mQuestionView.setText(ques.mQuestion); | |
mAdapter.setQuestion( ques); | |
} | |
void displayPreviousQuestion() | |
{ | |
if (mAnsweredQuestions.isEmpty()) | |
return; | |
Question prevQuestion = mAnsweredQuestions.remove( mAnsweredQuestions.size() -1 ); | |
setupQuestion(prevQuestion); | |
} | |
void startQuestions() | |
{ | |
mAnsweredQuestions.clear(); | |
mAdapter = new QuestionAdapter(); | |
mOptionView.setAdapter(mAdapter); | |
//Display first question with these options | |
setupQuestion( new AgeQuestion( Age.CHILD, Age.ADULT) ); | |
mBackButton.setEnabled(true); | |
} | |
@Override | |
protected void onCreate(Bundle savedInstanceState) | |
{ | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
mQuestionView = findViewById(R.id.question_text); | |
mOptionView = findViewById(R.id.question_options); | |
mBackButton = findViewById(R.id.button_back); | |
mRestartButton = findViewById(R.id.button_restart); | |
mBackButton.setOnClickListener(new View.OnClickListener() | |
{ | |
@Override | |
public void onClick(View v) | |
{ | |
displayPreviousQuestion(); | |
} | |
}); | |
mRestartButton.setOnClickListener(new View.OnClickListener() | |
{ | |
@Override | |
public void onClick(View v) | |
{ | |
startQuestions(); | |
} | |
}); | |
//Display first question | |
startQuestions(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment