Android - Loop random array and don't repeat - android

I am a beginner in Android App development. The code below is a quiz app and I want it to loop random questions and don't repeat the question, I tried to use a flag2 to randomly generate questions but I was getting compile errors, can anyone help me out with this. I'm also a beginner in Java.
TextView tv;
Button btn1;
RadioButton rb1,rb2,rb3;
RadioGroup rg;
String Questions[]={"What is 1+1?","Capital of USA?","What is 2+2","Echo with Laughter","Warg"};
String opt[]={"2","3","4", "New York","Washington DC","Maryland", "5","4","6","Stairway to Heaven","Hotel California","Highway to hell","Jon","Bran","Dario" };
String ans[]={"2","Washington DC","4","Stairway to heaven","Bran"};
int flag=0;
public static int correct;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tv=(TextView)findViewById(R.id.textView2);
btn1=(Button)findViewById(R.id.button2);
rg=(RadioGroup)findViewById(R.id.radioGroup);
rb1=(RadioButton)findViewById(R.id.radioButton);
rb2=(RadioButton)findViewById(R.id.radioButton2);
rb3=(RadioButton)findViewById(R.id.radioButton3);
tv.setText(Questions[flag]);
rb1.setText(opt[0]);
rb2.setText(opt[1]);
rb3.setText(opt[2]);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RadioButton uans = (RadioButton) findViewById(rg.getCheckedRadioButtonId());
String ansText = uans.getText().toString();
if (ansText.equalsIgnoreCase(ans[flag])) {
correct++;
}
else {
Intent in = new Intent(getApplicationContext(),Token.class);
startActivity(in);
}
flag++;
if (flag < Questions.length) {
tv.setText(Questions[flag]);
rb1.setText(opt[flag * 3]);
rb2.setText(opt[(flag * 3)+1]);
rb3.setText(opt[(flag * 3)+2]);
}
else {
Intent in = new Intent(getApplicationContext(),Token.class);
startActivity(in);
}
}

use java.lang.Math.random().
it will return values from 0.0 to 0.1 convert those values in integer & get the question of the integer

Generate random number within the range which here would be from 0 to Maximum number of question, you can do it like below:
int numberOfQuestion = 5;
Random rn = new Random();
randomNum = rn.nextInt() % numberOfQuestion; // random number from 0 to MaxRange - 1
Instead of using three arrays you can create a class:
class Quiz{
String question;
String answer;
String[] options;
boolean asked;
}
And every time when the particular question is asked just make the flag asked to true, and before asking question just check if that question is asked or not, if not then only display the question.

Three string array actualy useless. You should use object ArrayList.
public class QuestionObject{
int id;
String question;
String [] options;
String answer;
--you should implement getter and setter--
public int getId(){
return this.id;
}
public void setId(int id){
this.id= id;
}
public String getQuestion(){
return this.question;
}
public void setQuesion(String question){
this.question = question;
}
public String[] getOptions()
{
return options;
}
public void setOptions(String[] options)
{
this.options= options;
}
public int getOptionsElement(int location)
{
return options[location];
}
public void setOptionsElement(int value, int location)
{
options[location] = value;
}
public String getAnswer(){
return this.answer;
}
public void setAnswer(String answer){
this.answer= answer;
}
}
And you should use this like
ArrayList<QuestionObject> questionObject = new ArrayList<QuestionObject>();
ArrayList<QuestionObject> answeredQuestion = new ArrayList<QuestionObject>();
Don't forget fill the questionObject with your Question options and aswers.
After that your logic must be implement.you can take the id of question when question display and remove the list. May be you can push the removed question another Arraylist.
//take the diplaying question this id can be your random number
int id = questionObject.getId(); //or int id = yourRandomNumber;
//store the another arraylist this question
answeredQuestion.add(questionObject.get(id));
//remove it from list than never show again
questionObject.remove(id);
I think this may help you.

EDIT:
This is due to while goes infinite, New declarations as Lists:
Random random = new Random();
String rightAnswer=null;
List<String> questions=new ArrayList<String>(); // list of questions
List<String> answers=new ArrayList<String>(); // list of answers
String[] ques={"What is 1+1?","Capital of USA?","What is 2+2","Echo with Laughter","Warg"};
questions.addAll(Arrays.asList(ques));
String[] ans={"2","Washington DC","4","Stairway to heaven","Bran"};
answers.addAll(Arrays.asList(ans));
ArrayList<String[]> options = new ArrayList<String[]>(); // list of arrays that holds options
String[] opt1={"2","3","4"};
String[] opt2={"New York","Washington DC","Maryland"};
String[] opt3={"5","4","6"};
String[] opt4={"Stairway to Heaven","Hotel California","Highway to hell"};
String[] opt5={"Jon","Bran","Dario" };
options.add(opt1);
options.add(opt2);
options.add(opt3);
options.add(opt4);
options.add(opt5);
And where you want to generate question you can write this code, I am assuming in onClick() of Button:
int questionNumber;
if(questions.size()>0) // only run if list contains something
{
questionNumber = random.nextInt(questions.size()); // generate random question from current list
String[] currentOptions=options.get(questionNumber);
tv.setText(questions[questionNumber]);
rb1.setText(currentOptions[0]);
rb2.setText(currentOptions[1]);
rb3.setText(currentOptions[2]);
rightAnswer=answers.get(questionNumber); // hold right answer in this variable
questions.remove(questionNumber); // remove question which is asked
answers.remove(questionNumber); // remove answer which is asked
options.remove(questionNumber); // remove options that are showed
}
else
{
tv.setText("No questions remaining");
}
This is tested, and I was able to get these results:
NOTE: Declaration part must be outside the function that generates random question, otherwise it will fail.

Related

How to split phrase into word and display corresponding image in each word?

I've already tried this codes below but it only reads word not a phrase and this codes worked and didn't meet what I want.Each word that the user input it will only add and add to an empty array-list. What I want to achieve is when an user input a phrase it will split by space and store in an empty array-list. That array-list will compare to another array-list that contains words when the condition is true it will display a corresponding image and will now read the next word in the phrase.
private List<String> wordsList;
private ArrayList<String>wordsToDisplay=new ArrayList<>();
boolean missingGIF;
int counter;
wordsList= new ArrayList(Arrays.asList(getResources().getStringArray(R.array.sample)));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String input = editText.getText().toString();
String[]splited = input.split("//s+");
int count = splited.length;
for(int i=0;i<count;i++){
String word = splited[i];
if(wordsList.contains(word)){
wordsToDisplay.add(splited[i]);
}
else
missingGIF = true;
}
sample();
}
});
}
This is the sample method.
if(wordsToDisplay.size()>0){
counter=0;
gifImageView.setImageResource(getResources().getIdentifier(wordsToDisplay.get(0),"drawable",getPackageName()));
animation = (GifDrawable)gifImageView.getDrawable();
resetAnimation();
startAnimation();
animation.addAnimationListener(this);
}
And this is my animation listener which display corresponding images in all the words that have been inputted by the user.
#Override
public void onAnimationCompleted(int loopNumber) {
if(wordsToDisplay.size()>1){
if(counter<wordsToDisplay.size()){
try{
counter++;
gifImageView.setImageResource(getResources().getIdentifier(wordsToDisplay.get(counter),"drawable",getPackageName()));
animation = (GifDrawable)gifImageView.getDrawable();
resetAnimation();
startAnimation();
animation.addAnimationListener(this);
}
catch(IndexOutOfBoundsException e){
Log.d("Expected",e.toString());
}
}
}
}
Remove counter and use below logic
#Override
public void onAnimationCompleted(int loopNumber) {
if(!wordsToDisplay.isEmpty()){
String nextWord = wordsToDisplay.remove(0);
gifImageView.setImageResource(getResources().getIdentifier(nextWord,"drawable",getPackageName()));
animation = (GifDrawable)gifImageView.getDrawable();
resetAnimation();
startAnimation();
animation.addAnimationListener(this);
}
}

How to get object boolean type in an if statement

I have a constructor class object here:
public class Question {
public String question;
public boolean correctAnswer;
public Question(String question, boolean correctAnswer)
{
this.question = question;
this.correctAnswer = correctAnswer;
}
}
In my MainActivity I am creating questions and storing them in a List.
Then i want to make an f/else statement on button click so that when a user clicks button and the questions boolean type matches the if statement it is prompted to another question. The problem is I dont know how to get the questions boolean type.
public class MainActivity extends ActionBarActivity {
Button mYes;
Button mNo;
TextView mQuestion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final int[] count = {0};
mYes = (Button)findViewById(R.id.button2);
mNo = (Button)findViewById(R.id.button);
mQuestion = (TextView)findViewById(R.id.textView);
//Creating question
final Question first = new Question("Do i understand this code?", false);
final Question second = new Question("kas tas?", true);
//question list
final ArrayList<Question> questions = new ArrayList<Question>();
//adding question
questions.add(first);
questions.add(second);
//show the question.
mQuestion.setText(questions.get(0).question);
mYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if () {
count[0]++;
mQuestion.setText(questions.get((count[0]) % questions.size()).question);
} else {
finish();
}
}
});
I can get one Questions boolean type by writing first.correctAnswer. However I need all of the questions. Should I count all the questions with a for statement? If so how do I extrect the boolean type from that?
You should make a boolean arrayList to keep answers i.e. true, false, true, true ...
ArrayList<boolean> answers = new ArrayList<boolean>();
As you are already keeping the count of the question,
You should match the answer from the list onClick event...
if (answers.get(count[0])) { // if answer == true
count[0]++; // increase count
/// do whatever you want
}

how to go back and forth between records loaded onto an arraylist

I am building an app which requires a back and next button to show records retrieved from a database. i have loaded the records in an arrayList and now I am facing the dilemma of how to make my records switch back and forth on button click, i.e how to manipulate the records in the list. Please help.
List<Question> questionList = new ArrayList<Question>();
Cursor cursor = myDataBase.rawQuery(selectQuery, null);
if(cursor != null && cursor.getCount()>0){
if(cursor.moveToFirst()){
//do a loop to get all the questions
do{
Question quest = new Question();// create a new Question object
quest.setID(cursor.getInt(0));//get the question id for the cursor and set it to the object
quest.setQUESTION(cursor.getString(1));//same here for the question and the answers
quest.setCorrectAnswer(cursor.getString(2));
questionList.add(quest);//finally add the question to the list
}while(cursor.moveToNext());//move to next question until you finish with all of them
}
}
else {
Toast.makeText(myContext, "No records yet!", Toast.LENGTH_SHORT).show();
}
this is how I load my records into the arrayList, from my activity i do a loadPrevious and loadNext method to go back and forth on button click, I have done the loadNext part and it works, I just don't know how to implement the loadPrevious button.
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//currentQ.setChoice(num);
loadNextQuestion();
}
});
protected void loadNextQuestion() {
// TODO Auto-generated method stub
Log.e(TAG,"load next question original");
if (questions.size() > 2)
{
currentQ = questions.remove(0);
}
question.setText(currentQ.getQUESTION());
correctAnswer = currentQ.getCorrectAnswer();
answer.setText(correctAnswer);
}
and the Question list looks like this
package com.threeleafsoln.questionanswer;
public class Question {
private int ID;
private String QUESTION;
private String ANSWER;
public Question()
{
ID=0;
QUESTION="";
ANSWER="";
}
public Question(String qUESTION, String cORRECT_ANSWER) {
QUESTION = qUESTION;
ANSWER = cORRECT_ANSWER;
}
public int getID()
{
return ID;
}
public String getQUESTION() {
return QUESTION;
}
public String getCorrectAnswer() {
return ANSWER;
}
public void setID(int id)
{
ID=id;
}
public void setQUESTION(String qUESTION) {
QUESTION = qUESTION;
}
public void setCorrectAnswer(String aNSWER) {
ANSWER = aNSWER;
}
}
You just need to maintain the counter as per which record is being shown currently.
Firstly, when you show 1st ever question from arraylist, initialize that counter to question number. (assume its 1st question = 0th element of ArrayList)
So, it will be:
qCounter = 0;
Now increase counter by 1 in Next's onClick and decrease counter by 1 in Previous's onClick.
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(qCounter < questions.size()){ //i.e. its not last question of list
loadNextQuestion();
qCounter++;
}
}
});
prev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(qCounter > 0){ //i.e. its not first question of list
loadPreviousQuestion();
qCounter--;
}
}
});
protected void loadNextQuestion() {
//show item with index = (qCounter + 1)
currentQ = questions.get(qCounter + 1);
question.setText(currentQ.getQUESTION());
correctAnswer = currentQ.getCorrectAnswer();
answer.setText(correctAnswer);
}
protected void loadPreviousQuestion() {
//show item with index = (qCounter - 1)
currentQ = questions.get(qCounter + -1);
question.setText(currentQ.getQUESTION());
correctAnswer = currentQ.getCorrectAnswer();
answer.setText(correctAnswer);
}
Hope this helps.
An iterator for lists that allows the programmer to traverse the list in either direction. Instead of removing the question from the ArrayList, you can just refer them using index.
Refer this link for an example
ListIterator<Question> itr=questionList.listIterator();
protected void loadNextQuestion() {
if (itr.hasNext){
currentQ = itr.next();
question.setText(currentQ.getQUESTION());
correctAnswer = currentQ.getCorrectAnswer();
answer.setText(correctAnswer);
}
}
protected void loadPreviousQuestion() {
if (itr.hasPrevious){
currentQ = itr.previous();
question.setText(currentQ.getQUESTION());
correctAnswer = currentQ.getCorrectAnswer();
answer.setText(correctAnswer);
}
}

Using NumberPicker Widget with Strings

Is there a way to use the Android NumberPicker widget for choosing strings instead of integers?
NumberPicker picker = new NumberPicker(this);
picker.setMinValue(0);
picker.setMaxValue(2);
picker.setDisplayedValues( new String[] { "Belgium", "France", "United Kingdom" } );
NumberPicker numberPicker = new NumberPicker(this);
String[] arrayString= new String[]{"hakuna","matata","timon","and","pumba"};
numberPicker.setMinValue(0);
numberPicker.setMaxValue(arrayString.length-1);
numberPicker.setFormatter(new NumberPicker.Formatter() {
#Override
public String format(int value) {
// TODO Auto-generated method stub
return arrayString[value];
}
});
String value = String.valueOf(picker.getValue());
You could mean something else, but it isn't very clear what you mean.
UPDATED:
You can fake it by setting your own formatter:
CountryFormatter implements Formatter {
public String toString(int value) {
switch(value) {
case 0:
return "England";
case 1:
return "France";
}
return "Unknown";
}
}
picker.setFormatter(new CountryFormatter());
getValue() will still return an int, so you probably want to map the names of countries to their ids.
ADDED:
The implementation of NumberPicker has:
public void setRange(int start, int end, String[] displayedValues)
Which seems to do a better job of what you want then the above formatter.. although it isn't mentioned in the documentation so probably isn't part of the public api
try this solution, may help you
NumberPicker pickers = new NumberPicker(this);
String[] arrayPicker= new String[]{"abc","def","ghi","jkl","mno"};
//set min value zero
pickers.setMinValue(0);
//set max value from length array string reduced 1
pickers.setMaxValue(arrayPicker.length - 1);
//implement array string to number picker
pickers.setDisplayedValues(arrayPicker);
//disable soft keyboard
pickers.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
//set wrap true or false, try it you will know the difference
pickers.setWrapSelectorWheel(false);
//create button to test selected text string
btnPicker.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//get position (int) from number picker
int pos = pickers.getValue();
//get string from number picker and position
String selecPicker = arrayPicker[pos];
//test toast to get selected text string
Toast.makeText(context, selecPicker , Toast.LENGTH_SHORT).show();
}
});
This worked for me.
public class YourClassName extends AppCompatActivity {
NumberPicker picker = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity_layout_file);
picker = (NumberPicker) findViewById(R.id.pickerId_From_your_Layout_file);
picker.setMinValue(0);
picker.setMaxValue(3);
picker.setDisplayedValues(new String[]{"English", "French","Kiswahili","عربى"});
}
}

Regarding android Development

I am doing an application in which I have to display the numbers on TextView randomly and automatically with the help of Timer. I am able to get the random Numbers in the log without repeating, but I am not able to print the same on device please help me...
Regards,
Akki
Source:
//RandomNumber.java
public class RandomNumber extends Activity{
static Random randGen = new Random();
int tambolanum,count=0;
private Button previousbutton;
private Button startbutton;
private Button nextbutton;
int bingonum[]=new int[90];
boolean fill;
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.numbers);
LinearLayout number=(LinearLayout)findViewById(R.id.numbersview);
final TextView randomnum=(TextView)findViewById(R.id.numberstext);
previousbutton=(Button)findViewById(R.id.previous);
nextbutton=(Button)findViewById(R.id.next);
startbutton=(Button)findViewById(R.id.start);
startbutton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on click
//--- Initialize the array to the ints 0-90
do{
fill = true;
//Get new random number
tambolanum = randGen.nextInt(90) + 1;
//If the number exists in the array already, don't add it again
for(int i = 0; i < bingonum.length; i++)
{
if(bingonum == tambolanum)
{
fill = false;
}
}
//If the number didn't already exist, put it in the array and move
//To the next position
if(fill == true)
{
bingonum[count] = tambolanum;
count++;
}
} while(count < 90);
for(i=0;i
{
randomnum.setText(Integer.toString(bingonum[i]);
}
}
setText(CharSequence text)
The problem you're having is that you're overwriting your text in every itteration of this loop:
for(i=0;i
{
randomnum.setText(Integer.toString(bingonum[i]);
}
You need to build your string first then set it. Something like:
StringBuilder sb = new StringBuilder();
for(i=0;i /* where's the rest of this for-statement? */
{
sb.append(Integer.toString(bingonum[i]);
}
randomnum.setText(sb.toString());

Categories

Resources