I want to make a Hint button, so when I click on it, I want to delete two buttons from the list (answers list). Now I don't know how to do it,ho w to make the for loop on the button array, so I can make this buttons invisible.
public class ClassicMode extends Activity {//מהמשחק עצמו
String pic;//תמונה של הדגל
Button answer1;//תשובות
Button answer2;
Button answer3;
Button answer4;
Button hint;
TextView guess;
TextView numOfGuess;
TextView score;
TextView scorenum;
DatabaseHandler db = new DatabaseHandler(this);
String fn;
Guesses G;
Bitmap bm;
Score s;
Button [] b = new Button[4];
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
score =(TextView)findViewById(R.id.score);
scorenum =(TextView)findViewById(R.id.scorenum);
scorenum.setText(String.valueOf(s.score));
guess =(TextView)findViewById(R.id.guesses);
numOfGuess=(TextView)findViewById(R.id.numOfGuesses);
numOfGuess.setText(String.valueOf(Guesses.numOfGuesses));
hint =(Button)findViewById(R.id.hint);
Flags f = new Flags();
Random r = new Random();//הדגל שיבחר לשאלה
int num = r.nextInt(160);//Up
f = db.getFlag(num);//הצגת הדגל הרנדומלי שיצא
fn = f.getName().toString();
pic = f.getImage().toString();
pic_view(pic);//מעבר לפונקציה להשמת התמונה של הדגל במשחק
//מערך ארבע כפתורים כנגד ארבע תשובות
b[0] = (Button)findViewById(R.id.button1);
b[1] = (Button)findViewById(R.id.button2);
b[2] = (Button)findViewById(R.id.button3);
b[3] = (Button)findViewById(R.id.button4);
List<String>Answers=new ArrayList<String>();//מערך תשובות
Answers.add(f.getName().toString());//הוספת התשובה הנכונה
for(int i=1;i<4;i++)
{
num = r.nextInt(200);
String valToAdd1 = db.getFlag(num).getName().toString();
if(!Answers.contains(valToAdd1)){
Answers.add(valToAdd1);
}
}
/*num = r.nextInt(30);
Answers.add(db.getFlag(num).getName().toString());//הוספת 3 תשובות רנדומליות
num = r.nextInt(30);
Answers.add(db.getFlag(num).getName().toString());
num = r.nextInt(30);
Answers.add(db.getFlag(num).getName().toString());*/
Collections.shuffle(Answers);//ערבוב התשובות
for(int i=0;i<Answers.size();i++)
{
b[i].setText(Answers.get(i));//השמת התשובות מהמהערך למערך הכפתורים
}
}//end of OnCreat
Now what I've done (there is the function check, which check if you answered correctly and the hint which I don't know how to make):
public void check(View v)
{
Log.d("yes", fn);
Button b = (Button)v;
String text = b.getText().toString();
if(text.equals(fn))
{
s.score+=5;
resetQuiz();
}
else
{
s.score-=5;
if(Guesses.numOfGuesses==1)
{
G.setNumOfGuesses(3);
finish();//כאשר מספר הניחושים
return;
}
Guesses.numOfGuesses--;
numOfGuess.setText(String.valueOf(Guesses.numOfGuesses));
}
}
public void hint(View v)
{
G.numOfGuesses--;
for(int i=0;i<2;i++)
for(int j=0;j<4;j++)
{
if()
}
}
Note: this is {mostly} pseudocode
I suggest keeping two separate lists of your answers. Your Flag object already holds the correct answer. You need a list to keep track of the wrong answers (so we don't have to loop and check against each item every time). You also need a list of all of them together that you can shuffle and display.
I took a little bit of liberty making your variable names longer so they are more clear.
onCreate() {
...
btnHint.setOnClickListener(hintOnClickListener);
...
Flag f = db.getFlag(randomNum); // This is the real question & answer
List<String> wrongAnswers = new ArrayList<String>(3);
List<String> allAnswers = new ArrayList<String>(4);
// Loop 3 times for 3 random wrong answers
for (int i=0; i<=3; i++) {
randNum = r.nextInt(200);
String randWrongAnswer = db.getFlag(randNum).getName().toString();
if (! wrongAnswers.contains(randWrongAnswer)) {
wrongAnswers.add(randWrongAnswer);
}
}
allAnswers.add(f.getName().toString());
allAnswers.addAll(wrongAnswers);
Collection.shuffle(allAnswers);
...
}
I like to declare all my listeners separately further down in the code, to keep the OnCreate method clean and legible.
private OnClickListener hintOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
G.numOfGuesses--;
// Since you shuffled the 'allAnswers' before displaying to the screen,
// we can just pick the first 2 answers from wrongAnswers list
// and it will appear to be random to the user.
for (int i=0; i < buttons.length; i++) {
String buttonText = buttons[i].getText().toString();
if (buttonText.equals(wrongAnswers.get(0))
|| buttonText.equals(wrongAnswers.get(1))) {
buttons[i].setVisibility(View.INVISIBLE);
}
}
}
};
Edit: to add hint logic based on OP's comment.
Related
In my app have twenty edit text,but I want to count filled edit text and that data goes in anther activity through an array. Like when I filled 3 edit text from twenty, that 3 edit text data goes next page and that 3 count goes to next page as an int.
this is my 1st java class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select);
mspin=(Spinner) findViewById(R.id.spinner1);
submit = (Button) findViewById(R.id.btn1);
layout = (LinearLayout) findViewById(R.id.linear);
lay = (LinearLayout) findViewById(R.id.li);
edt=(EditText) findViewById(R.id.ed2);
sc = (ScrollView) findViewById(R.id.sc1);
int no = 20;
allEds = new ArrayList<EditText>();
for (int i=1;i<=no;i++){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
edtAdd = new EditText(SelectActivity.this);
layout.setLayoutParams(params);
allEds.add(edtAdd);
edtAdd.setHint("Enter Name" + i);
edtAdd.setId(i);
layout.addView(edtAdd);
}
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (allEds.size()<=9) {
Intent data = new Intent(SelectActivity.this, HalfPieChartActivity.class);
String[] items = new String[allEds.size()];
String str = String.valueOf(allEds.size());
data.putExtra("size", str); //you don't need to keep this in loop as its same.
data.putExtra("edt", edt.getText().toString());
for (int j = 0; j < allEds.size(); j++) {
items[j] = allEds.get(j).getText().toString();
data.putExtra("edData" + j, items[j]);
}
startActivity(data);
}
else {
Intent data = new Intent(SelectActivity.this, FullPieChartActivity.class);
String[] items = new String[allEds.size()];
String str = String.valueOf(allEds.size());
data.putExtra("size", str);// this is the line where I sent that count
data.putExtra("edt", edt.getText().toString());
for (int j = 0; j < allEds.size(); j++) {
items[j] = allEds.get(j).getText().toString();
data.putExtra("edData" + j, items[j]);//here is filled data send line
}
startActivity(data);
}
}
});
}
}
When I click submit 20 show in next page as an int.I want to sent that 3data and 3 as an int.
Please help me
As you have asked for sample in comment, i am posting my answer with sample.
In onclicklistener of your submit button you can add following code.
myNoneEmptyEdittextCounter = 0;
for (int i=1;i<=no;i++)
{
myEt = (EditText) findViewById(i);
if(!TextUtils.isEmpty(myEt.getText().toString()))
{
myNoneEmptyEdittextCounter +=1;
}
}
//myNoneEmptyEdittextCounter is count of your filled edittexts
This method will return list of data and its size will give you the int you are looking for which is number of filled items.
In submit button click
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(edittextValues().isEmpty()) {
//nothing has been filled
} else {
//items in edittextValues() are your data.
edittextValues().size();//this is your int which is number of edit text filled.
}
}
}
I have mentioned in comments what each step does. Hope this helps.
Method edittextValues()
ArrayList<String> edittextValues() {
ArrayList<String> filledData = new ArrayList<>(); //initialise empty string array.
for (int i=1; i<=20; i++){ //loop through ids from 1 to 20
for (int j = 0; j< layout.getChildCount(); j++) { //loop through all the children of root layout
if(layout.getChildAt(j) instanceof EditText) { //filter EditText
EditText editText = (EditText) layout.getChildAt(j);
if(editText.getId() == i) { // filter the one which u programmatically added
if(!editText.getText().toString().isEmpty()) { // check if its not empty, that's the one you are looking
filledData.add(editText.getText().toString()); //add it to the list
}
}
}
}
}
return filledData; //return string list
}
When I compare demDigits.equals(Numbers[i][j]) the if is only true with the last value in the 2d array which is 666, every other value from 111-555 is false. Can't figure out why
public class MainActivity extends AppCompatActivity {
EditText digits;
EditText console;
Button press;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String[][] Numbers = {
{"111", "222"},
{"333", "444"},
{"555", "666"}
};
digits = (EditText) findViewById(R.id.editText4);
console = (EditText) findViewById(R.id.editText5);
press = (Button) findViewById(R.id.button3);
press.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String demDigits = digits.getText().toString();
for (int i = 0; i < Numbers.length; i++)
{
for(int j = 0; j < Numbers[i].length; j++ )
{
if (demDigits.equals(Numbers[i][j]))
{
console.setText("works");
//break;
}
else
{
console.setText("nope");
}
}
}
}
});
}
}
You may be getting more than you bargained for from your digits.getText() method as #Ekundayo has pointed out within a comment of the code he posted. Check it, you should get a string length of 3 in order to make a proper comparison:
final String demDigits = digits.getText().toString();
// Read LogCat to see output with method below
// or use whatever you want to display desired
// output.
Log.d("demDigits", "demDigits Length = " + demDigits.length());
It's never a bad thing to trim User input since additional spaces are easy for a User to apply during that input. For some people it's a downright habit. As #Ekundayo has already suggested:
final String demDigits = digits.getText().toString().trim();
should take care of that issue.
Since you have a commented break statement within your code it is naturally assumed that you would like to break out of your for loops once a successful comparison has been made. This makes total sense since it's a waste of time to process any further unless of course you actually want to. As #1blustone has already pointed out within his comments, to properly break out of both inner and outer for loops you're going to need more than one break statement, you'll need one for each loop. Here is how you can accomplish this:
final String demDigits = digits.getText().toString().trim();
for (int i = 0; i < Numbers.length; i++) {
boolean mustBreak = false;
for(int j = 0; j < Numbers[i].length; j++ ) {
if (demDigits.equals(Numbers[i][j])) {
console.setText("works");
mustBreak = true;
break;
}
else {
console.setText("nope");
}
}
if (mustBreak) { break; }
}
but for some reason, I think you already know this ;)
I'm currently working on a school project (a small android game) and so far I've written a code which generates a random equation 2 seconds after the activity InGame is launched and displays it in a textview. Another 5 seconds later, the second equation is generated and displayed in a different textview. Now the user has to decide if the second equation has a bigger result than the first one by either pressing the button bigger or smaller. If it was correct, the next equation should be displayed and it would go on like this until the user decided wrong.
Here is my code so far:
(Code for the first equation):
// Generate random equation and display it in textview
String[] operationSet = new String[]{"+", "-", "/", "*"};
String equation;
static double doubleAnswer1;
public void start1() {
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(4)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(10)+1;
numbers.add(number);
}
String equation = "";
for (int i = 0; i < numOfOperations; i++) {
equation += numbers.get(i);
equation += operations.get(i);
}
equation += numbers.get(numbers.size() -1);
TextView TextEquation = (TextView)findViewById(R.id.textView_first_equation);
TextEquation.setText(equation);
// Evaluate the result of the equation
double doubleAnswer1 = eval(equation);
String stringAnswer = Double.toString(doubleAnswer1);
TextView textAnswer = (TextView)findViewById(R.id.textView4);
textAnswer.setText(stringAnswer);
}
(Code for second equation (basically same as for first equation except the name of the strings and doubles are different)):
String equation2;
static double doubleAnswer2;
public void start2() {
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(4)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(10)+1;
numbers.add(number);
}
String equation2 = "";
for (int i = 0; i < numOfOperations; i++) {
equation2 += numbers.get(i);
equation2 += operations.get(i);
}
equation2 += numbers.get(numbers.size() -1);
TextView TextEquation = (TextView)findViewById(R.id.textView3);
TextEquation.setText(equation2);
// Evaluate the result of the equation
double doubleAnswer2 = eval(equation2);
String stringAnswer = Double.toString(doubleAnswer2);
TextView textAnswer = (TextView)findViewById(R.id.textView_result2);
textAnswer.setText(stringAnswer);
}
And here is my onCreate code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ingame);
// Display first equation 2 seconds after the activity is launched
final Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
start1();
}
}, 2000);
final Handler handler2 = new Handler();
handler2.postDelayed(new Runnable() {
#Override
public void run() {
start2();
}
}, 7000);
// Check if user was right or wrong
final Button buttonBigger = (Button)findViewById(R.id.button_bigger);
final Button buttonSmaller = (Button)findViewById(R.id.button_smaller);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.equals(buttonBigger) && doubleAnswer1 < doubleAnswer2) {
Log.v("TAG", "you are right");
} else if(v.equals(buttonSmaller) && doubleAnswer1 > doubleAnswer2) {
Log.v("TAG", "you are right");
} else {
Log.v("TAG", "you are wrong");
}
}
};
buttonBigger.setOnClickListener(listener);
buttonSmaller.setOnClickListener(listener);
}
The app launches correctly and it also displays the first and second equation, but when I press one of the button, it tells me in the logcat you are wrong but I decided 100% correct. However if I debug the app, it tells me that doubleAnswer1 and doubleAnswer2 are both = 0. That's why it all ways tells me 'you are wrong'. I don't know how to fix this, maybe I need to store the doubleAnswer1 and doubleAnswer2 somewhere.
I really don't know what to do, so it would really help me if someone has an idea what to do.
If anything is unclear in my question, feel free to ask and I will try to clarify the problem.
Thank you in advance for your help!
I think your problem lies here:
double doubleAnswer1 = eval(equation);
I did a quick internet search and did not find any native function called eval(). Instead you should look into Script Engine Manager for java:
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
or exp4j which is shown here:
Executing math equation in Android
Edit:
change the following:
double doubleAnswer1 = eval(equation);
to:
doubleAnswer1 = eval(equation);
Similarly do the same for doubleAnswer2
So, I'm developing an app for my graduation final project and in my app I have a layout with an imageView and a textView, to set the content of these elements I receive an ArrayList as a parameter and use the setText(), and it works.
But my Arraylist has more than one element, and my big problem is that I want to change the content of the imageView and the textView when I click in a button.
The way I was thinking was that when I click the button it will increment the value and change the content of the objects for the next element inside the arrayList.
I've faced problems with global variables inside onClickListeners, but I solved them with auxiliar methods, but this time that doesn't work since I need to increment the value of the iteration inside the button event.
Can you guys please help me with suggestions or tell me what I'm I doing wrong?
I hope you understand my problem, and I'm sorry if I didn't explain me well, feel free to ask any questions and request more blocks of code if what I post isn't enough.
Thanks in advance to all you guys, i apreciate all the help you can give me!
To get the data from my db and store it into an arraylist
private ArrayList<Exercises> getExercisesSelectedPlan() {
ArrayList<ProgramExercises> arrayList_programExercises = new ArrayList<();
ArrayList<Exercises> arrayList_exercises = new ArrayList<>();
Button btnNext = (Button) findViewById(R.id.btnFinishAquecimento);
//with the id of the selected plan, select all the exercises from the plan and load them into the layout
int idProgram = getIdPlan();
DatabaseHelper databaseHelper = new DatabaseHelper(this);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
String queryProgramExercises = "SELECT * FROM PROGRAM_EXERCISES WHERE PROGRAM_ID_PROGRAM = " + "'" + idProgram + "'" + " ORDER BY ORDER_EX ASC";
Cursor cursorProgramExercises = db.rawQuery(queryProgramExercises, null);
int numRows = cursorProgramExercises.getCount();
if (numRows > 0) {
cursorProgramExercises.moveToFirst();
while (numRows > 0) {
for (int i = 0; i < cursorProgramExercises.getCount(); i++) {
ProgramExercises nProgramExercises = new ProgramExercises();
nProgramExercises.setIdProgramExercises(cursorProgramExercises.getInt(0));
nProgramExercises.setOrder(cursorProgramExercises.getString(1));
nProgramExercises.setRepetition(cursorProgramExercises.getInt(2));
nProgramExercises.setIdExercises(cursorProgramExercises.getInt(3));
arrayList_programExercises.add(nProgramExercises);
numRows--;
}
}
}
//for each select result from program_exercises i have to select the exercise with the id correspondent to nProgramExercies.getidExercises
for (int i = 0; i < arrayList_programExercises.size(); i++) {
String queryExercises = "SELECT * FROM EXERCISES WHERE ID_EXERCISES = " + "'" + arrayList_programExercises.get(i).getIdExercises() + "'";
Cursor cursorExercises = db.rawQuery(queryExercises, null);
cursorExercises.moveToNext();
if (cursorExercises.getCount() > 0) {
Exercises exercises = new Exercises();
for (int j = 0; j < cursorExercises.getCount(); j++) {
exercises.setIdExercises(cursorExercises.getInt(0));
exercises.setMedia(cursorExercises.getString(1));
exercises.setDesignation(cursorExercises.getString(2));
exercises.setIdExercisesPhase(cursorExercises.getInt(3));
arrayList_exercises.add(exercises);
cursorExercises.moveToNext();
}
cursorExercises.close();
}
}
cursorProgramExercises.close();
db.close();
databaseHelper.close();
}
Where I want to change the content of the textview and increment the iteration when I click btnNext
public void prepareExercise(final ArrayList<Exercises> exercises) {
setContentView(R.layout.activity_execute_ex_warmup);
TextView txtPrepare = (TextView) findViewById(R.id.tvAquecimento);
ImageView imageExercise = (ImageView) findViewById(R.id.ivAquecimento);
Button btnNext = (Button) findViewById(R.id.btnFinishAquecimento);
txtPrepare.setText(exercises.get(1).getDesignation());
imageExercise.setImageResource(R.drawable.imgTest);
for (int i = 0; i < exercises.size(); i++) {
if (exercises.get(i).getIdExercisesPhase() == 1) {
txtPrepare.setText(exercises.get(i).getDesignation());
System.out.println("------ TEST" + exercises.get(i).getDesignation());
}
}
//Click Next Button
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//for (int i = 1; i < exercises.size(); i++) {
//TextView txtPrepare = (TextView) findViewById(R.id.tvAquecimento);
//txtPrepare.setText(exercises.get(finalI).getDesignation());
//}
//executeExercise(); //next Exercise
}
});
}
How I invoke the previous method
prepareExercise(getExercisesSelectedPlan());
Hopefully I'm understanding correctly.
If you just want to update the views each time the button is clicked the easiest way would be just to create a variable and store the position of the array list.
public int listIncrement = 0;
private TextView txtPrepare;
private ImageView imageExercise;
Then in your prepareExercise() method
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listIncrement <= excersises.size()) {
executeExercise(excersises, listIncrement); //next Exercise
listIncrement++;
}
}
});
and then in executeExercise(ArrayList exercises, int position) //guessed method name, can be whatever you like
txtPrepare.setText(exercises.get(position).getDesignation());
imageExercise.setImageResource(R.drawable.imgTest);
public class Music extends Activity {
private int [] layouts = {
R.layout.question_selector,
R.layout.question_selector2,
R.layout.question_selector3,
R.layout.queston_selector4,
R.layout.question_selector5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
int i = layouts.length;
Random r = new Random();
while (--i > 0) {
int j = r.nextInt(i + 1);
//swap values
int temp = layouts[j];
layouts[j] = layouts[i];
layouts[i] = temp;
}
setContentView(layouts[i]);
}
}
Here's what i have done so far: it works just fine, but I have notice that there are times that some layouts are shown over and over again. What I want is that when I press the button and it generates a layout randomly, the next time I'll press the button again it should not repeat the layout that had been shown before. How can I do such thing?
You can create an arrayList and then shuffle it instead of an array with Random, this will make it random but only use every item once
EDIT, code example:
ArrayList<int> mArrayList = new ArrayList<int>;
//OR ArrayList<int> mArrayList = new ArrayList<int>(Arrays.asList(mOrdinaryArray));
mArrayList.put(R.blabla.blabla);
mArrayList.put(R.blabla.blablatwo);
Collections.shuffle(mArrayList);
Log.d(TAG, "output after shuffle: " + mArrayList);