looping through an array backwards from current position - java

I am quite new to java and android so be patient with me. I have an xml layout containing two buttons. One containing text of "previous" and the other "next". I also have a class containing array of strings which loops in an ascending order in a textView when a "next" button is clicked.
What i want is that i want the array to loop backwards from its current position when the "previous" button is clicked. Any ideas?
Question Class
// This file contains questions from QuestionBank
class Question{
// array of questions
private String mQuestions [] = {
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
// method returns number of questions
int getLength(){
return mQuestions.length;
}
// method returns question from array textQuestions[] based on array index
String getQuestion(int a) {
return mQuestions[a];
}
}
Main Activity.java
public class MainActivityextends AppCompatActivity {
private QuestionLibraryBeginner mQuestionLibrary = new QuestionLibraryBeginner();
private int mQuestionNumber = 1; // current question number
//initialising navigation buttons
private Button mPrevious;
private Button mNext;
private TextView mQuestionText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beginner_review);
mPrevious = (Button) findViewById(R.id.previous);
mNext = (Button) findViewById(R.id.next);
mQuestionText = (TextView) findViewById(R.id.txtQuestion);
// receive the current question number from last activity by Intent
Intent intent = getIntent();
currentQuestionNumber = intent.getIntExtra("quizNumber", 0); // receiving the number of questions the user has attempted from previous activity
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// checking against total number of questions the user has attempted instead of total number of questions from Question Class
if (mQuestionNumber < currentQuestionNumber) {
updateQuestion();
}
});
mPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// i want it to loop backwards from here
}
});
// logic to update question from array
private void updateQuestion() {
if (mQuestionNumber < mQuestionLibrary.getLength()) {
mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
mQuestionNumber++;
}
}
}

I would suggest to do this:
1) Rename updateQuestion method to nextQuestion
2) Create a method to decrease the mQuestionNumber like this:
private void prevQuestion(){
if(mQuestionNumber > 0){
mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
mQuestionNumber--;}
}

Here's a solution accounting for bounds
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
showNextQuestion();
}
});
mPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
showPreviousQuestion();
}
});
private void showNextQuestion() {
showQuestion(1);
}
private void showPreviousQuestion() {
showQuestion(-1);
}
private void showQuestion(int increment) {
int newQuestionNumber = mQuestionNumber + increment;
if (newQuestionNumber >= 0 && newQuestionNumber < mQuestionLibrary.getLength()) {
mQuestionNumber = newQuestionNumber;
mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
}
}

It can be done by just adding a flag to mention the move,
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateQuestion(true);
});
mPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateQuestion(false);
}
});
And the method would look like:
private void updateQuestion(boolean forward) {
if(forward && mQuestionNumber < mQuestionLibrary.getLength())
mQuestionNumber++
else if (mQuestionNumber>1)
mQuestionNumber--;
mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
}

I would change the following methodes:
would remove mQuestionNummer++; from update question.
You can increment mQuestions directly in the onClickMethode of NextButton.
So you can implement your solution simply by decrement mQuestion-- in onClick of previous Button.
Code would look like this:
public class MainActivityextends AppCompatActivity {
private QuestionLibraryBeginner mQuestionLibrary = new
QuestionLibraryBeginner();
private int mQuestionNumber = 1; // current question number
//initialising navigation buttons
private Button mPrevious;
private Button mNext;
private TextView mQuestionText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beginner_review);
mPrevious = (Button) findViewById(R.id.previous);
mNext = (Button) findViewById(R.id.next);
// receive the current question number from last activity by Intent
Intent intent = getIntent();
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mQuestionNumber < mQuestionLibrary.getLength()) {
mQuestionNumber++;
updateQuestion();
}
});
mPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// i want it to loop backwards from here
if(mQuestionNumber > 0){
mQuestionNumber--;
updateQuestion();
}
else
{}//don't do anything to prevent IndexOutOfBounds
}
});
// logic to update question from array
private void updateQuestion() {
if (mQuestionNumber < mQuestionLibrary.getLength()) {
mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
}
}
}

You need to don't mess logic of your application with view logic, decouple them.
Just make class Question able to provide previous and next questions. Also according to oop principles (solid, grasp) fetch information from class and make decision outside is wrong, make class to do it's work. Oop it's about telling classes to do things, not work instead of them.
class Questions {
private int index = 0;
private String[] mQuestions;
//better to don't hardcode and provide questions in constructor
public Question(String[] questions) {
this.questions = questions;
}
//we don't need this method
int getLength(){
return mQuestions.length;
}
//provide human readable information about current position in question list
// when you want to provide this information to user introduce label field in activity
public String currentPosition() {
int questionPosition = index + 1;
int questionsLength = mQuestions.length;
return String.format("current question number is %d from %d" , questionPosition, questionsLength);
}
//return next question when available, if next not available returns last question from array
public String next() {
int lastIndex = mQuestions.length - 1;
if(index < lastIndex) {
index++;
}
return mQuestions[index];
}
//return current question
public String current() {
return mQuestions[index];
}
//return previous question when available, if previous not available returns first question from array
public String previous() {
int firstIndex = 0;
if(index > firstIndex) {
index--;
}
return mQuestions[index];
}
}
And how to use it in Activity:
public class MainActivity extends AppCompatActivity {
//better to don't hardcode here, but provide this class from
//constructor of MainActivity just like questions array provide
// to constructor in Questions class
private Questions questions = new Questions(new String[]{"q1","q2"});
private Button mPrevious;
private Button mNext;
private TextView mQuestionText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beginner_review);
mPrevious = (Button) findViewById(R.id.previous);
mNext = (Button) findViewById(R.id.next);
Intent intent = getIntent();
//when create Activity populate question field with first question
mQuestionText.setText(questions.current());
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mQuestionText.setText(questions.next());
}
});
mPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mQuestionText.setText(questions.previous());
}
});
}
}
p.s. you may improve this code further in way to introduce Observer pattern, Activity is a view, Questions is model.

Related

I don't understand this error message, any help would be helpful

I tried to build my app, and this error message was produced.
Unexpected character '=' (code 61) (expected a name start character)
at [row,col {unknown-source}]: [41,21]
I have cleaned my code and tried to clean my code and inspected my code and i can't find anything wrong my code, and help would be gratefully recieved.
This is my MainActivity.
package com.michaeldoughty.android.football_quiz;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import
androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.*;
import java.text.DecimalFormat;
public class MainActivity extends AppCompatActivity
{
// to answer true for the question
private Button mTrueButton;
// to answer false for the question
private Button mFalseButton;
// to get the next question
private ImageButton mNextButton;
// to cheat
private Button mCheatButton;
// to hold the questions
private TextView mQuestionTextView;
// whether the user is a cheater
private boolean mIsCheater;
// a key used for the onSaveInstanceState
private final String KEY_INDEX = "index";
// An ActivityResultLauncher for the CheatActivity
ActivityResultLauncher<Intent> cheatActivityResultLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>()
{
#Override
public void onActivityResult (ActivityResult
result)
{
//checking if there is a result code from the
returned intent
if (result.getResultCode () == RESULT_OK)
{
// to check is there is any data in the
returned intent
if (result.getData() == null)
{
return;
}
// setting that the user is a cheater
mIsCheater = true;
}
}
});
// an array of Question objects
private Question [] mQuestionBank = new Question []
{
new Question (R.string.question_euro, true),
new Question (R.string.question_world_cup, false),
new Question (R.string.question_premier_league,
false),
new Question (R.string.question_england, true),
new Question (R.string.question_fa_cup, false),
new Question (R.string.question_league_cup, true)
};
// the index of the current question being displayed
private int mCurrentIndex = 0;
// to hold the percentage of correct answers
private double percentage = 0;
// to hold the amount of correct answers
private double correct = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// to check if there is a value of mCurrentIndex in the
savedInstanceState
if (savedInstanceState != null)
{
mCurrentIndex = savedInstanceState.getInt (KEY_INDEX,
0);
}
// to create the mQuestionTextView
mQuestionTextView = (TextView) findViewById
(R.id.question_text_view);
mQuestionTextView.setOnClickListener(new
View.OnClickListener()
{
#Override
public void onClick(View view)
{
// update the mCurrrentIndex
mCurrentIndex++;
// enable the mTrueButton and mFalseButton
mTrueButton.setEnabled (true);
mFalseButton.setEnabled (true);
if (mCurrentIndex < 6)
{
// call the updateQuestion method
updateQuestion();
}
else
{
displayPercentage ();
mCurrentIndex = 0;
updateQuestion();
}
}
});
// call the updateQuestion method
updateQuestion ();
// to create the mTrueButton
mTrueButton = (Button) findViewById (R.id.true_button);
mTrueButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
// call the checkAnswer method
checkAnswer (true);
// disable the mTrueButton and mFalseButton
mTrueButton.setEnabled (false);
mFalseButton.setEnabled (false);
}
});
// to create the mFalseButton
mFalseButton = (Button) findViewById (R.id.false_button);
mFalseButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
// call the checkAnswer method
checkAnswer (false);
// disable the mTrueButton and mFalseButton
mTrueButton.setEnabled (false);
mFalseButton.setEnabled (false);
}
});
// to create the mNextButton
mNextButton = (ImageButton) findViewById
(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
// update the mCurrrentIndex
mCurrentIndex++;
// enable the mTrueButton and mFalseButton
mTrueButton.setEnabled (true);
mFalseButton.setEnabled (true);
if (mCurrentIndex < 6)
{
// call the updateQuestion method
updateQuestion();
}
else
{
displayPercentage ();
mCurrentIndex = 0;
updateQuestion();
}
}
});
// to create the mCheatButton
mCheatButton = (Button) findViewById (R.id.cheat_button);
mCheatButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
boolean answerIsTrue = mQuestionBank
[mCurrentIndex].isAnswerTrue ();
Intent intent = CheatActivity.newIntent
(MainActivity.this, answerIsTrue);
cheatActivityResultLauncher.launch (intent);
}
});
}
/**
The onSaveInstanceState method saves savedInstanceState when
the activity is stopped.
#param savedInstanceState, the bundle of the activity.
*/
#Override
public void onSaveInstanceState (Bundle savedInstanceState)
{
// call the super's constructor
super.onSaveInstanceState (savedInstanceState);
// to add the mCurrentIndex to the bundle
savedInstanceState.putInt (KEY_INDEX, mCurrentIndex);
}
/**
The updateQuestion method updates the question.
*/
public void updateQuestion ()
{
// get the next question
int question = mQuestionBank [mCurrentIndex].getTextResId
();
// to display the next question
mQuestionTextView.setText (question);
}
/**
The checkAnswer method checks the user's answer, to see if
its correct or not
#param userPressedTrue, the user's answer.
*/
public void checkAnswer (boolean userPressedTrue)
{
// getting the correct answer
boolean answerIsTrue = mQuestionBank
[mCurrentIndex].isAnswerTrue ();
// the message in the toast
int messageResId = 0;
// checking the user's answer and setting the right meassge
if (userPressedTrue == answerIsTrue)
{
messageResId = R.string.correct_toast;
correct++;
}
else
{
messageResId = R.string.incorrect_toast;
}
// displaying the meessage in a toast
Toast toast;
toast = Toast.makeText(this, messageResId,
Toast.LENGTH_SHORT);
toast.setGravity (Gravity.TOP|Gravity.CENTER, 0, 0);
toast.show ();
}
/**
The displayPercentage displays the percentage of correct
answers the user had guessed.
*/
public void displayPercentage ()
{
// working out the percentage
percentage = (correct / mQuestionBank.length) * 100;
DecimalFormat df = new DecimalFormat("#.00");
// displaying the percentage as a toast
Toast.makeText(this, "You have guessed " +
df.format(percentage) + "%!", Toast.LENGTH_SHORT).show ();
// to set the correct and percentage back to zero
correct = 0;
percentage = 0;
}
}
Here is my CheatActivity
// an extra key for the intent which tells the CheatActivity
what the answer is
private static final String EXTRA_ANSWER_IS_TRUE =
"com.michaeldoughty.android.football_quiz_answer_is_true";
// an extra key for the intent which tells the MainActivity if
the user has cheated
private static final String EXTRA_ANSWER_IS_SHOWN =
"com.michaeldoughty.android.football_quiz_answer_shown";
// if the answer is true or not
private boolean mAnswerIsTrue;
// to hold the correct answer
private TextView mAnswerTextView;
// a button to show the correct answer
private Button mShowAnswerButton;
// to create an intent to create a CheatActivity
public static Intent newIntent (Context packageContext,
boolean answerIsTrue)
{
Intent intent = new Intent (packageContext,
CheatActivity.class);
intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);
return intent;
}
public static boolean wasAnswerShown (Intent result)
{
return result.getBooleanExtra (EXTRA_ANSWER_IS_SHOWN,
false);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
// to get the mAnswerIsTrue
mAnswerIsTrue = getIntent ().getBooleanExtra
(EXTRA_ANSWER_IS_TRUE, false);
// to create the mAnswerTextView
mAnswerTextView = findViewById (R.id.answer_text_view);
// to create the mShowAnswerButton
mShowAnswerButton = findViewById (R.id.show_answer_button);
mShowAnswerButton.setOnClickListener(new
View.OnClickListener()
{
#Override
public void onClick(View view)
{
if (mAnswerIsTrue)
{
mAnswerTextView.setText (R.string.true_button);
}
else
{
mAnswerTextView.setText
(R.string.false_button);
}
setAnswerShownResult (true);
}
});
}
/**
The setAnswerShownResult creates an Intent, to send the
isAnswerShown to the MainActivity.
#param isAnswerShown, whether the user has cheated or not.
*/
private void setAnswerShownResult (boolean isAnswerShown)
{
Intent data = new Intent ();
data.putExtra (EXTRA_ANSWER_IS_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
}
Here is my Question class
package com.michaeldoughty.android.football_quiz;
public class Question
{
// to hold the text res id of the question
private int mTextResId;
// to hold if the answer is true or false
private boolean mAnswerTrue;
/**
Constructor
*/
public Question (int textResId, boolean answerTrue)
{
mTextResId = textResId;
mAnswerTrue = answerTrue;
}
public int getTextResId()
{
return mTextResId;
}
public void setTextResId(int textResId)
{
mTextResId = textResId;
}
public boolean isAnswerTrue()
{
return mAnswerTrue;
}
public void setAnswerTrue(boolean answerTrue)
{
mAnswerTrue = answerTrue;
}
}

Product Subtract Button is not working perfectly in ecommerce app

I am facing issue while subtracting my product, I am using three buttons to get the value of the selected one and then multiply these value for add more product or subtract . But when i click on subtract button it will minus the whole amount. So please help me in this. Below mention is my code. If you want some more info then please ask me.
public class ShowDetailActivity extends AppCompatActivity {
private TextView addToCardBtn;
private TextView titleTxt, feeTxt, descriptionTxt, numberOrderTxt;
private ImageView plusBtn, minusBtn, picFood, priceBtn, mediumPriceBtn, largePriceBtn;
private ProductsDomain object;
private int numberOrder = 1;
private ManagementCart managementCart;
private LinearLayout cheese_ll;
private LinearLayout scale_ll;
private int itemPrice;
private CheckBox cheeseBoxyes;
private int price;
private int checkvalue;
private int uncheckValue;
private boolean cheeseBoolean = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_detail);
managementCart = new ManagementCart(this);
initView();
getBundle();
//Button Code
price=object.getPrice();
priceBtn.setOnClickListener(this::onClick);
mediumPriceBtn.setOnClickListener(this::onClick);
largePriceBtn.setOnClickListener(this::onClick);
//check box code for extra cheese
}
private void onClick(View view) {
int id=view.getId();
switch (id){
case R.id.smallPriceBtn:
price=object.getPrice();
itemPrice=object.getPrice();
feeTxt.setText(Integer.toString(price*numberOrder));
break;
case R.id.mediumPriceBtn:
price = object.getMediumPrice();
feeTxt.setText(Integer.toString(price*numberOrder));
itemPrice=object.getMediumPrice();
break;
case R.id.largePriceBtn:
price = object.getLargePrice();
feeTxt.setText(Integer.toString(price*numberOrder));
itemPrice=object.getLargePrice();
break;
}
}
private void getBundle() {
object = (ProductsDomain) getIntent().getSerializableExtra("object");
if (object.getWithCheese() == 1)//get cheese
{
cheese_ll.setVisibility(View.VISIBLE);
scale_ll.setVisibility(View.GONE);
} else {
cheese_ll.setVisibility(View.GONE);
scale_ll.setVisibility(View.VISIBLE);
}
Glide.with(this).load("http://192.168.100.215/pizzaVill/Images/" + object.getImage()).into(picFood);
titleTxt.setText(object.getName());
descriptionTxt.setText(object.getDescription());
numberOrderTxt.setText(Integer.toString(numberOrder));
feeTxt.setText(Integer.toString(object.getPrice()));
plusBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
numberOrder = numberOrder + 1;
numberOrderTxt.setText(Integer.toString(numberOrder));
feeTxt.setText(Integer.toString(numberOrder * price));
//Code if there is no size required
}
});
minusBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (numberOrder > 1) {
numberOrder = numberOrder - 1;
}
numberOrderTxt.setText(Integer.toString(numberOrder));
feeTxt.setText(Integer.toString(price - itemPrice));
}
});
addToCardBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
object.setNumberInCard(numberOrder);
object.setFinalPrice(price);
managementCart.insertFood(object);
}
});
}
private void initView() {
addToCardBtn = findViewById(R.id.addToCardBtn);
titleTxt = findViewById(R.id.titleTxt);
feeTxt = findViewById(R.id.priceTxt);
descriptionTxt = findViewById(R.id.descriptionTxt);
numberOrderTxt = findViewById(R.id.numberOrderTxt);
plusBtn = findViewById(R.id.plusBtn);
minusBtn = findViewById(R.id.minusBtn);
picFood = findViewById(R.id.foodPic);
priceBtn = findViewById(R.id.smallPriceBtn);
mediumPriceBtn = findViewById(R.id.mediumPriceBtn);
largePriceBtn = findViewById(R.id.largePriceBtn);
cheese_ll = findViewById(R.id.cheese_ll);
scale_ll = findViewById(R.id.scale_ll);
cheeseBoxyes = findViewById(R.id.cheeseBoxyes);
}

Making repetitive CountDownTimer with Different Times

I am trying to learn coding. So I decided to make a little project but i stuck.
I am trying to make a CountDownTimer. I have 3 different times. For example first one is 10 sec, second one 5 sec and the third one is 7 sec. So I wanna make an app that start the count from 10 sec and when it finish it start the count from second timer and then third one.
public class MainActivity extends AppCompatActivity {
private Button mStartButton;
private Button mResetButton;
private Button mStopButton;
private TextView mTextViewCountDown;
private TextView mTextViewCounter;
private CountDownTimer mCountDownTimer;
private int countme = 0 ;
private int [] array = new int[3];
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStartButton = findViewById(R.id.button_start);
mStopButton = findViewById(R.id.button_stop);
mResetButton = findViewById(R.id.button_reset);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mTextViewCounter = findViewById(R.id.text_s);
array[0]=10000;
array[1]=5000;
array[2]=70000;
mStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0; i<3; i++){
mCountDownTimer = new CountDownTimer(array[i], 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTextViewCountDown.setText(""+ millisUntilFinished/1000);
}
#Override
public void onFinish() {
countme++;
if(countme / 3 == 3){
mCountDownTimer.cancel();
}else{
start();
} } }.start();
}
}
}); } }
I don't think for loop is right for my problem. It does not increase variable i once, it increase in every ontick i guess. As a beginner, I couldn't figure out what should I do.
You do not need for loop try something like this:
private void startCountDowntimer(long millis, int count) {
count ++;
int finalCount = count;
new CountDownTimer(millis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTextViewCountDown.setText(""+ millisUntilFinished/1000);
}
#Override
public void onFinish() {
if (finalCount == 1) {
startCountDowntimer(5000, 1);
} else if (finalCount == 2) {
startCountDowntimer(7000, 2);
} else {
//all finished
}
}
}.start();
}
and on the button click:
mStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDowntimer(10000, 0);
}
});

how to get dynamic array value in a nested onclick method (android)?

I have an array of text views called plans and an array of integers called months, the text views are clickable and I want to take the value of one of the months' values inside OnClick Listener method but it shows either an error (when I initialize the months with a variable) or always zero (when I initialize the months with fixed size)
package //...
Import //...
public class saving_consultation extends AppCompatActivity {
private TextView[] plans;
private TextView firstplan;
private TextView altplan1;
private TextView altplan2;
private TextView altplan3;
int[] months; // months of all plans
int month; // used to select a month
private int N; // total number of plans and months
private int i;
// rest of the variables
protected void onCreate(Bundle savedInstanceState) {
firstplan = (TextView) findViewById(R.id.first_plan);
altplan1 = (TextView) findViewById(R.id.plan1);
altplan2 = (TextView) findViewById(R.id.plan2);
altplan3 = (TextView) findViewById(R.id.plan3);
N = 4;
months = new int[N];
plans = new TextView[N];
plans[0] = firstplan;
plans[1] = altplan1;
plans[2] = altplan2;
plans[3] = altplan3;
// some code
somebutton.setOnClickListener(new View.OnClickListener() {
// some code
for (i = 0; i < N; i++) {
plans[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new AlertDialog.Builder(saving_consultation.this)
.setTitle("title")
.setMessage("msg")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
try {
month = months[i];
// other code that adds to a database, works perfectly fine without using the month array
Toast.makeText(getApplicationContext(), "SUCCESS", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();
} // End catch
}}) // End yes dialog
.setNegativeButton(android.R.string.no, null).show();
}}); // End plans OnClick()
} // End for loop
}}); // End outter OnClick()
} // End OnCreat()
} // End class
I tried to putmonth = months[i] after the for loop directly but it always takes the last index, I don't know how to fix this

Android - How would I go about dynamically changing a clickListener

So I have an array of Buttons, and one fo them is the correct answer, while the other 3 are incorrect. on each question, however, the correct button changes. How would I go about updating my click listener? It seems like a simple enough problem maybe I just can't see the clear answer here...
Here is my code so far, thanks in advance:
int correctIndex=newQuestion(questionTextView,answerButtons);//CREATES A NEW QUESTION and returns the correct index (0-3);
answerButtons[correctIndex].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
correctDialog(questionTextView,answerButtons);
}
});
for (int i = 0; i < 4; i++) {
final int j = i;
if (j != correctIndex) {
answerButtons[j].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
wrongDialog(questionTextView, answerButtons);
}
});
}
}
Make a generic listener that you can add to all of the buttons and within that listener handle the logic for determining which one is correct as needed. For example:
class YourListener implements View.OnClickListener {
private int correctButtonId;
public YourListener(int correctButtonId) {
this.correctButtonId = correctButtonId;
}
#Override
public void onClick(View v) {
if (v.getId() == correctButtonId) {
// do stuff
} else {
// do other stuff
}
}
}
You can then set all of your n buttons to have this listener, and from outside the listener you can set the id of the correct button as needed.
Such as
// this is the id of the button that is correct, where x represents its index, which you know ahead of time
int id = answerButtons[x].getId();
for (int i = 0; i < 4; i++) {
answerButtons[i].setOnClickListener(new YourListener(id));
}
Edit to answer: how to call a method (in your case, correctDialog for example) from inside the listener.
One way is to make the listener an inner class inside your activity. So you have something (not tested, give it a try) like:
public class MainActivity extends AppCompatActivity {
private class YourListener implements View.OnClickListener {
private TextView textView;
private Button[] buttons;
private int correctButtonId;
public YourListener(TextView textView, Button[] buttons, int correctButtonId) {
this.textView = textView;
this.buttons = buttons;
this.correctButtonId = correctButtonId;
}
#Override
public void onClick(View v) {
if (v.getId() == correctButtonId) {
MainActivity.this.correctDialog(textView, buttons);
} else {
MainActivity.this.wrongDialog(textView, buttons);
}
}
}
}
I would set the same clickListener for all buttons, and move the logic there. Just check if button's index in array is the same as correct answer's index, no need to update clickListeners or set different.

Categories