I have created programmatically, 5 radio groups with 4 radio buttons each. I set OnClickListener on the reset button that i have created too. I want when someone clicks the button, to restart my activity. How is it even possible? When the app first time starts, it works fine but when i press the button to reload the activity, the emulator crashes. If i comment the lines where i create the radio groups and the radio buttons and i press the button, the activity is reloading fine otherwise i have this error: Unable to start activity ComponentInfo{...}: java.lang.ArrayIndexOutOfBoundsException: length=4; index=4. How can reload the activity without issues?
Here is my code:
answerGroup = new RadioGroup[5];
answer = new RadioButton[4];
int i = 0;
for (Question qn : questions) {
answerGroup[i] = new RadioGroup(this);
answerGroup[i].setOrientation(RadioGroup.VERTICAL);
int j = 0;
for (Answer an : answers) {
if (qn.getID() == an.getQuestion_id_answer()) {
answer[j] = new RadioButton(this);
answer[j].setText(an.getAnswer());
answerGroup[i].addView(answer[j]);
j++;
}
}
linearLayout.addView(answerGroup[i]);
i++;
}
restartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
}
});
Thanks!
The activity is probably trying to reference to old view elements (from before the Activity restart). Try to add your view components:
RadioGroup
RadioButton
As class variables. Can you try that and tell me what it is doing? I will update this answer according to the input you give me.
EDIT:
I assume that you are using a ArrayList<Question> and ArrayList<Answer> as the questions and answers variable.
for (Question qn : questions) {
RadioGroup answerGroup = new RadioGroup(this);
answerGroup.setOrientation(RadioGroup.VERTICAL);
for (Answer an : qn.getAnswers()) {
if (qn.getID() == an.getQuestion_id_answer()) {
RadioButton answer = new RadioButton(this);
answer.setText(an.getAnswer());
answerGroup.addView(answer);
}
}
linearLayout.addView(answerGroup);
}
Maybe you should add a getter method to your question called: getAnswers(); and a variable to your Question model called List<Answer> answers. Ofcourse, these answers need to be set before you try to do anything with them.
You must debug your code, probably not all your questions have 4 answers.
If one of your questions have more than 4 answers (eg: 5), and you try to loop through them you get the ArrayIndexOutOfBoundsException because j>=4.
As a solution: try to use a List for your RadioButtons:
List<RadioButton> answer = new ArrayList<RadioButton>();
And for each iteration add a new RadioButton:
answer.add(new RadioGroup(this));
PS: Also i suggest you to use recreate() method to reload/recreate your activity.
Related
So I'm trying to make a quiz in which I will have 4 buttons for possible answers. I want to check if the right button is pressed, if so I want to change the image for about 2 seconds and load the next question (which will be an image stored in an array) this will be in a for loop the length of the question array I believe?
I'm having some trouble with this, as I'm also unsure on how to load a new question and then it know which button needs to be pressed, for example. question 1 might need button 1 pressing but question 2 might be button 3 but I don't want to change activity.
creating the array and setting image view:
private int[] ImageArr = new int[5];
private ImageView image = (ImageView) findViewById(R.id.Question_ImgView);
filling array:
public void FillImage() {
ImageArr[0] = R.drawable.img1;
ImageArr[1] = R.drawable.img2;
ImageArr[2] = R.drawable.img3;
ImageArr[3] = R.drawable.img4;
ImageArr[4] = R.drawable.img5;}
this is then called in the "onCreate method" to fill array on launch
then i will have a questions method, this is where I want the before mentioned things to happen.
tldr; I need to know how to loop through an image array if correct button is pressed (correct button changes for each question), and change the text on the buttons, till all questions are answered.
any help would be appreciated, thanks in advance. :)
I think the best thing you should do is to create a Question class.
public class Question {
#DrawableRes
private int imageId;
private String[] answers;
private int correctAnswerIndex;
public Question(int imageId, int correctAnswerIndex, String... answers) {
this.imageId = imageId;
this.correctAnswerIndex = correctAnswerIndex;
this.answers = answers;
}
#DrawableRes
public int getImageId() { return imageId; }
public String[] getAnswers() { return answers; }
public int getCorrectAnswerIndex() { return correctAnswerIndex; }
}
This class represents a question. It has
an imageId field to store the image of the question
an answers field to store all the possible answers that the user can choose
a correctAnswerIndex to store the correct answer. This actually stores the index of the correct answer in the answers array. Say you have {"blue", "red", "green", "yellow"} as the answers array and the correct answer is blue, you will set the correct answer index to 0.
Don't understand how to use it? Let's see an example.
At the moment, you have an array of image ids. You should change that to an array of Questions.
private Question[] questions = new Question[4];
And your fillQuestion method would be:
questions[0] = new Question(R.drawable.sweeper_is_handsome, 0, "True", "False", "Maybe", "I don't know");
questions[1] = new Question(R.drawable.no_one_can_beat_jon_skeet_in_reputation, 1, "True", "False", "Maybe", "I don't know");
// you get the idea.
As you can see, the answer to the first question is "True" (correctAnswerIndex = 0) and that to the second question is "False" (correctAnswerIndex = 1).
Now you have an array full of questions. How do you display it?
I think you can work out how to display the image yourself, so let's focus on how to get the buttons working.
I guess your buttons will be in an array, right? If it is isn't, then you're totally doing this wrong. Just add four buttons to an array, it's simple.
You can use the same on click handler for each button. It doesn't matter. In the on click listener, you have a view parameter like this right?
public void buttonOnClick(View view) {
// ⬆︎
// here
}
If you are doing this right, view should be an item in your buttons array. You can use the indexOf method to get the index of the button in the array. If this index matches the correctAnswerIndex of the question, the user chose the correct answer!
But how do you know which question is displaying? You create a variable in your activity class called questionIndex to keep track of it! It should start at 0 and each time you display a new question, you increment it!
EDIT:
This is how your button on click handler would look like:
int pressedButtonIndex = btns.indexOf(view);
int correctAnswerIndex = questions[questionIndex].getCorrectAnswerIndex();
if (pressedButtonIndex == correctAnswerIndex) {
// This means the user chose the correct answer
if (questionIndex == 4) {
// This is actually the last question! No need to display the next!
return;
}
// load next question
questionIndex++;
someImageView.setImage(questions[questionIndex].getImageId());
for (int i = 0 ; i < 4 ; i++) {
btns[i].setText(questions[questionIndex].getAnswers()[i]);
}
// YAY! The next question is displayed.
} else {
// User chose the wrong answer, do whatever you want here.
}
I would like to give a general approach to your question, you can or may need to modify according to your needs,
You have an Image Array of questions and would like to know the correct Button was pressed or not, for that you will need the options and a correct answer to compare with the Button clicked to check if the correct Button was pressed or not,
and you do not need to loop through all the questions at once, what you can do is when the button is pressed, compare button text with the correct answer and if its correct then show the next question image, some code example for the same,
if(btnClicked.getText().toString().equals("Correct Answer")){
questionPos++;
imgView.setImageResource(questionPos);
// Update all the buttons as per the new options
btn1.setText(options1);
// .... like wise update other buttons
}
see if this makes sense
Edit
as per you are asking how to know which button is clicked you can do something like this ...
btn1.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
if(btn1.getText().toString().equals("Correct Answer")){
questionPos++;
imgView.setImageResource(questionPos);
// Update all the buttons as per the new options
btn1.setText(options1);
}
}
});
// Similarly you can do for all other buttons
I have an Activity from which I get some input that I must use afterwards. I get an Integer number from a NumberPicker and an ArrayList<String> from a multiple choice AlertDialog. In that Activity I also have a button that starts the "game". When the button is clicked I want to open a new Activity so I can use the Integer number and the ArrayList but I will lose them if I go to a new Activity. So my guess is I should create a new Layout from the current Activity and handle the input there. I need some TextViews and a counter that can be dynamically changed on button click. For example the first TextView will be the first element of that ArrayList. On button clicks the counter must add 1 (counter += 1). When the counter equals the Integer number from the NumberPicker (user input) the TextView must change from ArrayList(first element) to ArrayList(second element). I don't need help on the logic. This was just to clarify things. I need to know how to do that with a layout dynamically. I need some guidance how can I do that or is that the way to go (layout not Activity). Tutorial links/examples/advice will help me a lot.
When the button is clicked I want to open a new Activity so I can use
the Integer number and the ArrayList but I will lose them if I go to a
new Activity.
Look into the putStringArrayListExtra() method in the Intent class. This will allow you to pass your ArrayList to the new Activity:
List<String> stringArrayList = new ArrayList<>();
int intValue = 5;
Intent i = new Intent(ActivityOne.this, ActivityTwo.class);
i.putExtra("int_key", intValue);
i.putStringArrayListExtra("string_key", stringArrayList);
startActivity(i);
Java Android question
I have x, say 5, buttons in a row.
Each button has a different number value displayed on the button.
Button one is active, the rest are not- not clickable. They are greyed out.
To show Button 1 is active it fades up and down.
Once clicked the button pops up a message. The user Ok's that, this activates Button 2, and deactivates Button 1.
Then it happens through all buttons, one by one. The final button doesn't produce the pop up message.
My question...
I want to create a method that sets the first button as current and then once clicked sets the next as current, and so on.
Can anyone tell me how to do this? I don't need to know how to fade buttons etc, its literally how to set button as current, and within that method the user click sets the next button as current.
Many thanks in advance.
EDIT
OK, I've had a go...its not working, but it seems so close...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_workout_one);
int[] buttonIds = new int[] {R.id.button_1,R.id.button_2,R.id.button_3,R.id.button_4,R.id.button_5};
setButton(buttonIds);
}
private void setButton(int[] buttId){
int isCurrent = 0;
while(isCurrent < 5) {
Button currentButton = (Button) findViewById(buttId[isCurrent]);
//TODO Make current button pulse
currentButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.clearAnimation();
v.setBackgroundColor(0xFF00FF00);
v.setFocusable(false);
v.setFocusableInTouchMode(false);
v.setClickable(false);
setTimer();
isCurrent++;
}
});
I know that the problem is the isCurrent++ is not accessible outside the onClick method. How do I right this? Am I close or is this a major funk up and do I have to rethink?
Just use a global variable which track the current button, and check this variable to identify the current active button for determining the action in onClickListener. To fade out a button try this code snippet
button.setClickable(false);
button.setBackgroundColor(Color.parseColor("#808080"));
You need something like this:
private int activeButton = 1;
private void buttonClickHandler(){
switch(activeButton++){
case : 1
button1.setEnabled(true):
// show popup, hide/animate for button 1
break;
case : 2
button2.setEnabled(true);
// same for button 2
case : 3
// same for button 3
case : 4
// same for button 4
}
Lets say you have an object like this and you want to have the program go through each dynamically created Checkbox to see if it has not been checked.
If has not been checked, then the program should create a notification alerting the user that one or more of these objects has not been checked.
What is the best way to have the program identify whether the checkbox is checked or not?
Each time I run the program, it only applies to the last created Checkbox regardless of how many checked or unchecked checkboxes proceed it.
Thank you for your time.
View ObjectView;
CheckBox check;
//A whole bunch of code here.
public void onClick(View arg0) {
if (check==null){
}
else if (check==null || check.isChecked()){
}
else {
ObjectView.getId();
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getActivity())
.setSmallIcon(android.R.drawable.stat_notify_more)
.setContentTitle("Items missing")
.setContentText("One or more items are missing");
int ID_Notify = 01;
getActivity();
NotificationManager managenote = (NotificationManager)getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
managenote.notify(ID_Notify, mBuilder.build());
Im gonna help you with an example of my code and try to explain it, aware that im not gonna babysit you (means you cant just copy paste) because i still have some work to do.
First, a new dynamic spinner will be created everytime you click a button (inside onClick) :
Spinner spinner = new Spinner(this);
spinner.setAdapter(spinChildAdapter);
parentSpinner.addView(spinner);
spinner.setId(totalDynamicChild); //the spinner's id will be the increment from 0
spinnderIdList.add(totalDynamicChild); //list of the dynamic spinner ID
totalDynamicChild++;
Then, we can access those dynamic Spinners with :
for(int i = 0; i < totalDynamicChild; i++)
{
Spinner s = (Spinner)findViewById(spinnderIdList.get(i));
//do something with the spinner's object here
}
Feel free to comment if you have some questions.
I have a TabLayoutObjectActivity that shows 2 tabs with a different activity(TabActivity1 & TabActivity2).
I have another activity called ObjectActivity. It contains an array and if it is clicked I want the app to change to the TabLayoutObjectActivity (which shows TabActivity1 first) and sends a string from an array that clicked to TabActivity1.
I have tried some code but the app always wants to force close after I click one of the array list.
Intent i = null;
i = new Intent(this, TabLayoutObjekActivity.class);
Intent ii = null;
ii = new Intent(this, TabActivity1.class);
ii.putExtra("name", String.valueOf(menuArray[position].toString()));
startActivity(i);
startActivity(ii);
Please give me your opinion how to do this. Thanks :)
Refer to this. It explains how to solve your problem in detail. onclick even you can handle the issue.