In my app, I am trying to get my activity to change text on a button. When I call the ansGen() method in onCreate() , I get a black screen.
And after a while, an error comes up and the app closes.
But when the ansGen() method call in onCreate() is commented, it shows up alright (obviously without the functions of the ansGen() method.
Here is my code with the ansGen() method (without imports and onCreateOptionsMenu):
public class QuizActivity extends Activity
{
Button Answer1;
Button Answer2;
Button Answer3;
Button Answer4;
String[] QuestionArray =
{ "What element has atomic number 1?",
"What is the second most abundant element on Earth?",
"Element with symbol Li ?", "Has 4 protons?" };
String[] AnswerArray =
{ "Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon",
"Nitrogen" };
public String tempStringy="";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
int AnsArraylen=AnswerArray.length;
Answer1 = (Button) findViewById(R.id.Answer1);
Answer2 = (Button) findViewById(R.id.Answer2);
Answer3 = (Button) findViewById(R.id.Answer3);
Answer4 = (Button) findViewById(R.id.Answer4);
//AnswerArray[randAnswers[0]]
Answer1.setText("Hello");
Answer2.setText("Hello");
Answer3.setText("Hello");
Answer4.setText("Hello");
**ansGen(AnsArraylen);**
}
public void ansGen(int AnsArraylen)
{
Random randomizer=new Random();
int[] AnsVal={-1,-1,-1,-1};
int numchecker=0;
for (int x=0;x<4;x+=1)
{
int tempVal=randomizer.nextInt(AnsArraylen);
if (tempVal==AnsVal[0])
{
numchecker=1;
}
if (tempVal==AnsVal[1])
{
numchecker=1;
}
if (tempVal==AnsVal[2])
{
numchecker=1;
}
if (tempVal==AnsVal[3])
{
numchecker=1;
}
if (numchecker==0)
{
AnsVal[x]=tempVal;
}
if (numchecker==1)
{
x-=1;
}
}
tempStringy=AnswerArray[AnsVal[0]];
//Answer1.setText("Hup");
}
I have searched everywhere with no avail.
Thank you for any help!
When you call randomizer.nextInt(AnsArraylen) you can get values between 0 and 3, inclusive. If this tempVal is 0, you are fine, as you just set the AnsArray[x] to the current tempVal. However, what happens when tempVal is 1, for example? You go into none of those ifs, except for the last one, which sets x to -1, so on the next loop iteration it'll become 0 again. Besides whether this makes sense to you, the mistake is in the next line. You are in that case doing:
tempStringy=AnswerArray[AnsVal[0]];
but AnsVal[0] is still -1. You are therefore trying to do:
AnswerArray[-1]
That's where you are getting an Exception. Wrap that in a try-catch and print the stack trace to confirm. Perhaps you wanted to initialize AnsVal as:
int[] AnsVal={0,1,2,3};
I tested your code and find that
if (numchecker==1)
{
x-=1;
}
this condition in your code make the x for loop with value 1 so it will be infinitive loop each time x will be with value 2 this condition make x = 1 so the condition in loop x < 4 will not occur and you will get message with (wait or close program) message
i don't know your logic in code , so try to handler it
Related
My app uses a Random Number Generator to display random questions to the users but there is just one problem, this random numbers doesn't stop and will always generate a number which will show a different question always.
So i tried to stop that using a while and an if loop, after i wrote that, i notice that the app keep freezing.
what are the best ways to stop this Random number generator without freezing the app.
package com.myafrica.africaquiz;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.RadioButton;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
//this variable stores the total number of correct answers
int StoresTotalCorrectAnswer;
//this variable count the total number of RandomQuestions asked
int RandomNumberCounter;
//this variable stores the random numbers generated
int RandomNumber;
//variables of the views for public access to other classes
TextView TestQuestionID = null;
RadioButton AnswerA_ID = null;
RadioButton AnswerB_ID = null;
RadioButton AnswerC_ID = null;
RadioButton AnswerD_ID = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get the text view and stores it in this variable
TestQuestionID = findViewById(R.id.TestQuestion);
//get the radio button view and stores it in this variable
AnswerA_ID = findViewById(R.id.AnswerA);
AnswerB_ID = findViewById(R.id.AnswerB);
AnswerC_ID = findViewById(R.id.AnswerC);
AnswerD_ID = findViewById(R.id.AnswerD);
}
//When the onclicked() is clicked this method runs
public void GetNextQuestion(View view) {
RandomNumberGenerator();
}
//Creating a random number generator
public void RandomNumberGenerator() {
Random RanNum = new Random();
RandomNumber = RanNum.nextInt(4) + 1;
//to know how many times the random method has been called
while (RandomNumber >= 0) {
RandomNumberCounter++;
//to stop the questions from displaying once the required number is
//reached
if (RandomNumberCounter < 4) {
switch (RandomNumber) {
case 1:
Question1();
break;
case 2:
Question2();
break;
case 3:
Question3();
break;
case 4:
Question4();
break;
}
// not done with this part yet, but was trying to store the
//correct answers
if (RandomNumber == 1 && AnswerA_ID.isChecked()) {
StoresTotalCorrectAnswer++;
} else if (RandomNumber == 2 && AnswerA_ID.isChecked()) {
StoresTotalCorrectAnswer++;
} else if (RandomNumber == 3 && AnswerD_ID.isChecked()) {
StoresTotalCorrectAnswer++;
} else if (RandomNumber == 4 && AnswerA_ID.isChecked()) {
StoresTotalCorrectAnswer++;
}
}
// shows a different layout after the question stops showing
else {
Intent i = new Intent(this, Main2Activity.class);
startActivity(i);
}
}
}
/*
This part of the code will contain the answer part of this quiz app.
Each question is a method and that method will be called when the Next
button is clicked in the app.
When the button is clicked the setText() will automatically (re)set the
text in the question layout in the XML
*/
public void Question1() {
TestQuestionID.setText("Which part of Africa can Ghana be located");
AnswerA_ID.setText(" A: West Africa");
AnswerB_ID.setText(" B: East Africa");
AnswerC_ID.setText(" C: Central Africa");
AnswerD_ID.setText(" D: North Africa");
}
public void Question2() {
TestQuestionID.setText("What is the capital of Nigeria");
AnswerA_ID.setText(" A: Abuja");
AnswerB_ID.setText(" B: Kano");
AnswerC_ID.setText(" C: Lagos");
AnswerD_ID.setText(" D: Port Harourt");
}
public void Question3() {
TestQuestionID.setText("Which of these countries are not located in
Africa");
AnswerA_ID.setText(" A: Niger");
AnswerB_ID.setText(" B: Nigeria");
AnswerC_ID.setText(" C: Rwanda");
AnswerD_ID.setText(" D: Non of the Above");
}
public void Question4() {
TestQuestionID.setText("What is the estimated population of Africa, as at
2015");
AnswerA_ID.setText(" A: 1.2 Billion");
AnswerB_ID.setText(" B: 500 Billion");
AnswerC_ID.setText(" C: 2 Billion");
AnswerD_ID.setText(" D: 360 million");
}
}
i tired to make the comments on the code understandable, so anyone can understand what each section of the code will do.
NOTE: what i really need is a way to stop the random number generator which always bring about a random question after X times and displays a different layout which will show the total number of questions answered
Your while loop does not reach exit condition, that is why it is doing work indefinitely. What you should do is break out of the loop when you reach desirable condition. For example in your else statement where you start new Activity, you should put break; at the end:
...
int RandomNumberCounter = 0; // you have to assign a sum variable to be 0 or else it stores random value.
...
while (RandomNumber >= 0) {
RandomNumberCounter++;
if (RandomNumberCounter < 4) {
...
}
else {
Intent i = new Intent(this, Main2Activity.class);
startActivity(i);
break; // this breaks execution of your while loop
}
}
Good luck :)
Overview
Yes, you have some formatting issues with your code but I am going to go out on a limb here and assume you've started out recently because you've got an issue here that is fairly obvious.
The simple answer to your question is: You can't. What you want to do isn't possible. What you have created here is an infinite loop!
Here is what is happening:
You create a while loop and tell that loop: "Please continue repeating as long as the value of the variable 'randomNumbers' is greater than 0"
Inside of the loop, you are incrementing the value of 'randomNumbers' by 1 every time the while loop repeats.
What this means is that there's never a reason for your while loop to stop repeating!
Luckily, this is an easy fix. All we need to do is change what will make the while loop stop repeating.
Current while loop condition:
randomNumbers >= 0
Think about it like this: "When do I want my while loop to stop repeating? What am I counting?"
The answers to those questions will form what you need to change the while loop's condition to. I believe, the answer you need, is to change the while loop condition to this:
while(randomNumbers is <= howManyQuestionsIWant)
That will definitely solve your while loop repeating issue. Only quickly glancing at the rest of the code, there be other bugs in there but this will at least get you past the repeating loop of doom problem so you can start debugging the rest. Good luck!
I have a simple screen with two EditText Boxes and 1 button. I want users to be able to enter various integers into the boxes and the program will perform different operations based on the specific number entered into the box. I'm trying to have them only enter one number at a time but the code wont seem to execute unless both boxes have something in them. And I'm having the if statements check for nulls on the respective boxes before executing to determine which piece of code to execute.
public void button(View view) {
double x, y;
EditText freq1 = findViewById(R.id.freq1);
EditText freq2 = findViewById(R.id.freq2);
TextView str1 = findViewById(R.id.freqanswer);
TextView str2 = findViewById(R.id.injVolt);
TextView error1 = findViewById(R.id.error1);
String strf1, strf2;
strf1 = freq1.getText().toString();
strf2 = freq2.getText().toString();
try {
f1 = Double.parseDouble(strf1);
f2 = Double.parseDouble(strf2);
if ((f1 >= 225) & (f1 <= 312) & (strf1.isEmpty())) {
x = f1 + 20.6;
y = x / 4;
str1.setText(String.format("%.3f", y));
}
}
catch (Exception e){
error1.setText("splat");
}
finally {
InputMethodManager input = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
input.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
I included only 1 formula for the sake of brevity, but I'm going to be putting about 6 if statements, checking for number ranges and nulls on this button and I just need it to run with one box being empty. I know the formula works by having play with various outputs, it just won't run with the strf1.isEmpty(). Something has to be in that second box for the formula to execute.
Would appreciate any help
I think you should check before assigning:
if(strf1.isEmpty()){strf1="0";} //if assuming zero does not change the formula's output
if(strf2.isEmpty()){strf2="0";}
f1 = Double.parseDouble(strf1);
f2 = Double.parseDouble(strf2);
this way you are assured of a default value.
The code below is supposed to fade two ImageViews, one needs to fade in and the other out depending on the value of counter. For some reason when I run the code I get the following log output:
I/Info: One
I/Info Counter:: 1
I/Info: One
I/Info Counter:: 1
...
It never shows:
I/Info: Two
I/Info Counter:: 0
Can someone explain why this is happening?
Here's the code:
public void fade(View view) {
int counter = 0;
ImageView bale = (ImageView) findViewById(R.id.bale);
ImageView pogba = (ImageView) findViewById(R.id.pogba);
if (counter == 0) {
bale.animate().alpha(0f).setDuration(2000);
pogba.animate().alpha(1f).setDuration(2000);
Log.i("Info", "One");
counter = 1;
} else if (counter == 1){
pogba.animate().alpha(1f).setDuration(2000);
bale.animate().alpha(0f).setDuration(2000);
Log.i("Info", "Two");
counter = 0;
}
Log.i("Info Counter: ", String.valueOf(counter));
}
You're making a logical error, there is nothing syntactically wrong with your code. The scope of counter is where you're having trouble. counter is a local variable, it only exists in the fade(...) method. Every time you call fade() you recreate counter and initialize it to 0. Meaning even though you set it to 1 in the if statement, it will be 0 the next time you call fade(). You either need to make it a class variable or use the alternating approach I describe below.
Non If Statement Alternating Approach:
You don't need an if statement, simply get the alpha of pogba and bale and then when you set their alphas use 1f - pogba.getAlpha() and 1f - bale.getAlpha() (using whichever method returns their alphas). Using this approach will alternate between 1 and 0.
So your fade(View view) method would look similar to the following:
public void fade(View view) {
ImageView bale = (ImageView) findViewById(R.id.bale);
ImageView pogba = (ImageView) findViewById(R.id.pogba);
// I'm not familiar with the method to get the alpha
// so it might not be getAlpha()
bale.animate().alpha(1f - bale.getAlpha()).setDuration(2000);
pogba.animate().alpha(1f - pogba.getAlpha()).setDuration(2000);
}
You would of course need to do the following somewhere else in your code, possibly the constructor.
bale.setAlpha(1f); // I'm not familiar with the method to set the alpha
pogba.setAlpha(0f); // it might be setAlpha(), but I'm not sure
I am making a guessing game for as my School project, but I am quite new to Android Studio and Java.
At the moment my code looks like this:
public class MainActivity extends AppCompatActivity {
public int score = 0;
int random = random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button correct = (Button) findViewById(R.id.correct);
Button other = (Button) findViewById(R.id.other);
Button newGame = (Button) findViewById(R.id.newGame);
TextView words = (TextView) findViewById(R.id.words);
}
public Integer random (){
int random = (int )(Math.random() * 5);
return random;
}
private String list[] =
{"Dog", "Cat", "Mouse", "Elephant", "Rat", "Parrot"};
public void clickedButton(View view) {
TextView words = (TextView) findViewById(R.id.words);
if (view.getId()== R.id.newGame)
{
words.setText(list[random]);
score = 0;
Log.i("score", "score = " + score);
}
if (view.getId() == R.id.correct)
{
// set maybe new array so new textview does not give the same value
words.setText(list[random]);
score = score +1;
Log.i("score", "score = " + score);
}
if (view.getId() == R.id.other)
{
// set maybe new array so new textview does not give the same value
words.setText(list[random]);
Log.i("score", "score = " + score);
}
}
}
Idea is simple. I have my array with (at the moment) 6 words in it. So as I launch the game it gives me a random word on screen which I have to describe to others. If they guess it right I press correct, I get another word, if not I can pass and get another word... Well the problem I see is that there is chance that I get the same word over again. So I thought there should be a way how to fix this problem.
I thought about adding like if statements like if index 1 or 2 or 3 then give another word but if I had 100 words it would be monkey work to do it.
So I think there should be a chance how I can delete words from like temp. array, but there is no in-built method to do it.
I was reading that there are those arrayLists and lists but would not it be easier to use Array? and maybe some tips how to?
You can first Create an ArrayList (because it is more flexible):
List<String> list;
Then initialize the object in the constructor and shuffle the ArrayList like below:
list = new ArrayList<String>();
list.add("Dog");
list.add("Cat");
...
//or alternatively list.addAll(Arrays.asList(normalArray)); if you have your data in array
Collections.shuffle(list,new Random(System.nanoTime()); //randomly shuffles your list
Then you can keep track of the index of the last item you read:
int index = 0;
And every time you read an item just increase the index:
words.setText(list.get(index++));
This will do the trick
While there are a variety of ways solve your issue, personally I like mixing the array up (swapping places using random), then just keep an index on what word you are on in the array, so you don't have to keep track of the words in it.
I wrote a code for a similar program for doing a random shuffle on a deck of cards below, it goes through the int times amount, but you can remove it altogether and have a static loop value if you'd like:
// ...
// Random Shuffle
// Tip: Use this method to shuffle, may not be the fastest (not noticeable however), but it makes your array totally randomized.
public static void totalRandom(String[] array, int times)
{
// Random Initialize
Random randomGenerator = new Random();
// Variables
int first = 0;
int second = 0;
// Swap
for (int i = 0; i < times; i++)
{
// Generates number from 0 to array length
first = randomGenerator.nextInt(array.length);
second = randomGenerator.nextInt(array.length);
String word = array[second];
array[second] = array[first];
array[first] = word;
}
}
// ...
then after in your class you would want to write something along the lines of...
//...
int index = 0;
// ...
// Code for user input
// ...
if (userInput.equals(array[index]))
{
// do stuff
index++;
}
// ...
You can cache your last word. Add a String member variable.
...
public int score = 0;
public String cache; // new
Instead of using
words.setText(list[random]);
you can call a method to request a new word. You also save this word to the cache:
...
cache = getRandomWord();
words.setText(cache);
...
Your new method looks like this:
private String getRandomWord(){
int random = random();
String temp = list[random];
if(temp.equals(cache)){
temp = getRandomWord();
}
return temp;
}
Just put this method under your clickButton method. It takes a random word. Is the word equal to the previous word, the method will call itself again to pick another word. If not, it will return the new word.
There is no need to shuffle ArrayLists.
I think a more simple way is pop every shown text out from a copied list.
//when start a new game.
ArrayList<String> currentGameList = YourList.clone();
//when need next word.
String displayText = currentGameList.remove(randomIntInRestSize); //after called remove, you will get the object at list(index), and the object will be removed from the list.
Every game started, you just need to clone a new list from the original word list and play with the list.
I am trying to increment a counter variable (mPressCount) every time a button is pressed. My question is: will mPresscount be 1 before it gets to the third if statement, assuming that it was 0 when the button was clicked? In other words, when mPressCount++; is read, does it get incremented immediately or does the button need to be pressed again before the variable is incremented?
Here is my code:
mButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mPressCount < 2) {
mButton1.setText(mWord4);
mButton1.setClickable(false);
mButton1Pressed = true;
mPressCount++;
if(mButton7Pressed) {
mMatchedWord4 = true;
}
}
if(mPressCount == 1) {
//im going to do something if the count is at 1 like I hope
//it is...Thanks for your insights everyone
}
If mPressCount begins at zero when your button is pressed, your first if statement
if(mPressCount < 2) will be executed. Including mPressCount++; which will make
mPressCount = 1
The code will continue executing down the file until it reaches the third if statement if(mPressCount == 1) which will be executed because as we said previously, mPressCount = 1
Programs are like reading, they go line by line. Hope this helps :)
if mPressCount = 0, mPressCount < 2, then mPressCount++ will 1, it gets to the third if statement.
if mPressCount = 1, mPressCount < 2, then mPressCount++ will 2, it will not gets to the third if statement