I am new to Android programming and want to make a simple quiz that has around 50 questions. My problem is that I am unsure of how to do this without creating 50 individual layouts, java classes and activities. I would like each question to be different, and the format of the questions is multiple choice (A, B, C and D). Any helpful suggestions?
Thanks.
It's easy! Just create one acitivty and then update it's data every time user answers the question:
1) Changing TextView with question
2) Changing Buttons with answers
/*updating question
*questions is the list of questions obviously
*answers is the list of lists:) When you take a list from answers
*you get a list with
*4 items - they are the answers for current question
*/
public void updateQuestion() {
mQuestionTextView.setText(questions.get(currentQuestionNum));
mButtonA.setText(answers.get(currentQuestionNum).get(0));
mButtonB.setText(answers.get(currentQuestionNum).get(1));
mButtonC.setText(answers.get(currentQuestionNum).get(2));
mButtonD.setText(answers.get(currentQuestionNum).get(3));
}
EDIT:
public ArrayList<String> getAnswers(int questionsNumber) {
return ArrayList<String> currentQuestionAnswers = answers.get(questionsNumber);
}
At every question, you can do something like this:
TextView textview = (TextView) findViewById(R.id.question);
question.setText(current_question);
And for the multiple choice, if you are using a RadioGroup, you can have 4 textviews that correspond to each option and you can modify the text, depending on the question.
For recognizing which option has been selected, put this inside an onClickListener
radioGroup = (RadioGroup) findViewById(R.id.radio);
btnSend = (Button) findViewById(R.id.btnSend);
btnSend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// get selected radio button from radioGroup
int selectedId = radioGroup.getCheckedRadioButtonId();
// find the radiobutton by returned id
radioButton = (RadioButton) findViewById(selectedId);
}
});
Related
I dynamically create Buttons by entering a word. If I write "met", it appears on the screen - one Button per letter. The same thing happens for the next word I enter, and it appears below the previous word --- as shown in the image above.
When I click on a Button it turns green. My question is, what is the best way to disable the clicking of a row of Buttons. Meaning, if the user clicks on the 'm' in "met" I want the user to only be able to click on the Buttons in "met" and to not be able to click on any of the Buttons in "had", "goes", or "ran"
Here is my code:
EDIT
int size = enter_txt.getText().toString().length();
for (int i=0; i<size; i++){
final Button dynamicButtons = new Button(view.getContext());
dynamicButtons.setLayoutParams(rlp);
dynamicButtons.getLayoutParams().width = 130;
dynamicButtons.getLayoutParams().height = 130;
dynamicButtons.setTag("0");
dynamicButtons.setId(1);
dynamicButtons.setText(edit_text_array[i]);
dynamicButtons.setBackgroundResource(R.drawable.button);
button_list.add(dynamicButtons);
linearLayout2.addView(dynamicButtons, rlp);
dynamicButtons.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
int i=0;
LinearLayout ll = (LinearLayout) dynamicButtons.getParent();
for(i=0; i<list_of_ll.size();i++){
if (ll == list_of_ll.get(i)){
list_of_ll.get(i).setId(i);
break;
}
}
if(list_of_ll.get(i).getId()==i)
ButtonOnClick(view);
}
});
}
linearLayout2.setId(0);
linearLayout2.setTag("0");
list_of_ll.add(linearLayout2);
EDIT
I created a List of the LinearLayouts for each row of Buttons. The Buttons turn green if the id of the LinearLayout is set to 1. When I click on a Button I want that LinearLayout to stay at 1 and have all other rows/LinearLayouts set to 0 so they become unclickable.
Currently, every Button I click turns green even if it's in a different row. Can someone please help me solve this issue?
Why you don't set Id in the for loop so that you are able to refer and set the onlicklistener to null like jpcrow already mentioned.
Set Id like:
YourCreatedBtn.setId(i+1);
//Id's setted programmatically don't.
have to be unique... But they should be
a positive number (referring to the
android documentation)
And in your on click method simply set onclicklistener for specified Id's to null. Just a hint, hope it helps
Update regarding Thread-openers Comment
I found two simple ways but i would prefer the one which is not commented out in the buttonIsClicked:
LinearLayout llrow;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
llrow = (LinearLayout) findViewById(R.id.test_layout);
//Adding 5 Buttons
for(int i = 0; i<5; i++) {
Button mybtn = new Button(this);
//set LayoutParams here
mybtn.setId(5);
mybtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
buttonIsClicked(v);
}
});
llrow.addView(mybtn);
}
}
private void buttonIsClicked(View v) {
/*ArrayList<View> myButtons = llrow.getTouchables();
for(int i = 0; i < llrow.getChildCount(); i++){
myButtons.get(i).setOnClickListener(null);
}*/
for(int i = 0; i<llrow.getChildCount(); i++){
llrow.getChildAt(i).setOnClickListener(null);
}
}
It's just a simplified Version of your code, but i'm sure you will get the Content..
What if found out is, that you don't have to set the ID in both cases.. You can easily get all the child over
YourRowLinearLayout.getChildAt(starting from 0 to n-1-Views you added)...
I didn't found a way around the for-loop... But this small-little loop will not break your neck regarding to Performance..
The outcommented-code is the second Approach, finding all the Child over getTouchables which logically leads to an ArrayList and that's exactly the reason why i don't like it. You have to initialize an arraylist...... However, this also won't break your neck regarding to Performance but a penny saved is a penny got! ;) Hope it helps and everything is clear. Both of them work! Please mark as accepted answere if it fits your Needs...
You have to distinguish between the two rows, either add them to different ViewGroups or you can use View.setTag(int key, Object tag)
I am quite new to Android and this is my first application, so please correct if my question is not clear and I will gladly add more information about what I am trying to achieve.
I have a radio group built dynamically. Inside this radio group I would like to have another radio group, depending on the radio button chosen from the first group.
So, let's say I have an array list of items and for each item I have some sizes available (i.e: XS, S, L). If I check the radio button "XS", I would like to have another radio group with the available colors for the selected size, XS.
The way I have built this is by creating a radio group and it's radio buttons dynamically. Inside the method onCheckedChanged(), I am calling the method createRadioButtonsForAvailableColors(). This one creates the radio buttons with the necessary colors for the checked size, but once I check another size in the upper radio group, the new colors available for this size are added to the colors shown for the size selected before.
Thank you.
Here is my on create method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_product_details);
sizesList = getSizes(getIDFromPreviousActivity());
createRadioButtonsForAvailableSizes(sizesList);
}
Here is my creation for the radio group containing the radio buttons with the available sizes:
// creates the radio buttons with the available sizes
public void createRadioButtonsForAvailableSizes(ArrayList<String> sizeList) {
productDetailsLayout = (LinearLayout) findViewById(R.id.productDetailsLayout);
RadioGroup rg = new RadioGroup(this);
rg.setOrientation(RadioGroup.HORIZONTAL);
int n = sizeList.size();
final RadioButton[] rb = new RadioButton[n];
for(int i=0; i< sizeList.size(); i++) {
colorList = getColors(getIDFromPreviousActivity(),sizeList.get(i));
rg.setOrientation(RadioGroup.HORIZONTAL);
rb[i] = new RadioButton(this);
rg.addView(rb[i]);
rb[i].setText(sizesList.get(i).toString());
rb[i].setId(getIDForRadioButton(sizesList.get(i).toString()));
rb[i].setButtonDrawable(R.drawable.radiobuttonunchecked);
rb[i].setOnCheckedChangeListener(this);
}
productDetailsLayout.addView(rg);
productDetailsLayout.setPadding(50, 50, 50, 50);
}
Here is the creation of the colors (same as for the sizes):
// create radio buttons for available colors
public void createRadioButtonsForAvailableColors(ArrayList<String> colorList) {
Log.d("createRadioButtonsForAvailableColors","");
productDetailsLayout = (LinearLayout) findViewById(R.id.productDetailsLayout);
RadioGroup rg = new RadioGroup(this);
rg.setOrientation(RadioGroup.HORIZONTAL);
int n = colorList.size();
final RadioButton[] rb = new RadioButton[n];
for(int i=0; i< colorList.size(); i++) {
Log.d("color"+i,colorList.get(i));
rg.setOrientation(RadioGroup.HORIZONTAL);
rb[i] = new RadioButton(this);
rg.addView(rb[i]);
rb[i].setText(colorList.get(i).toString());
rb[i].setId(getIDForRadioButton(colorList.get(i).toString()));
rb[i].setButtonDrawable(R.drawable.radiobuttonunchecked);
rb[i].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override public void onCheckedChanged(CompoundButton button, boolean isChecked) {
button.setButtonDrawable(isChecked ? R.drawable.radiobuttonchecked : R.drawable.radiobuttonunchecked);
}
});
}
productDetailsLayout.addView(rg);
productDetailsLayout.setPadding(50, 50, 50, 50);
}
Here is my onCheckedChange method:
#Override
public void onCheckedChanged(CompoundButton button, boolean isChecked) {
button.setButtonDrawable(isChecked ? R.drawable.radiobuttonchecked : R.drawable.radiobuttonunchecked);
String text = button.getText().toString();
int productID = getIDFromPreviousActivity();
ArrayList<String> colorList = getColors(productID, text);
createRadioButtonsForAvailableColors(colorList);
}
The inner group is created right, but upon checking one size in the first group, it builds the subgroup radio buttons normally. If I click one size, it shows the available colors. But, on changing the size checked, the buttons showing the colors of the now selected size are added to the buttons shown before for the previous size selected. How can I cancel the inner buttons created when I selected first time the size and show only the available colors for the currently selected size?
I think this is maybe not the right approach to build it. So, I have 2 questions:
Usually, what would be the best way to do this? Since my inner radio group depends on the radio button chosen from the first group, I assume the creation of the inner group should be called inside the onCheckedChange() method. Should I start another activity from here or can I do it all in one activity?
If my approach is correct, can you please tell me how to delete the inner radio buttons created, in case the radio button from the main group is changed?
Thank you
So, if I understood this, the problem comes when you change the value of the sizes radio button, meaning the colors don't disappear.
Well, Java is all about a lot of boilerplating, and there's not pretty much to say (I'd probably go for a similar way).
You could add this inside the createRadioButtonsForAvailableColors method, just before you start adding content:
productDetailsLayout.removeViews(0, productDetailsLayout.getChildCount());
RemoveViews will remove any amount of child views starting from a position (hence I amb passing it 0 and the total of children).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I pass data between activities in Android?
Yes,No,Difficult are three RadioButtons and NEXT is a Button. I don't know how to pass the id's of selected radio button of each screen to last screen. In RESULT screen particular value is to displayed in TextView. Here is a code for one screen:
public class MainActivity extends Activity {
RadioGroup rg;
RadioButton rb;
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
addListenerOnButton();
}
private void addListenerOnButton() {
rg = (RadioGroup) findViewById(R.id.rg_Ques1);
b = (Button) findViewById(R.id.button1_ques1);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int selectedId = rg.getCheckedRadioButtonId();
rb = (RadioButton) findViewById(selectedId);
Intent i = new Intent(MainActivity.this,Ques2.class);
startActivity(i);
Toast.makeText(getApplicationContext(), rb.getText(), 0).show();
}
});
}
You can use intents or you can store the values in preferences and access preferences wherever you need.
My approach will be different here. I will make only one activity for all the questions. I will keep my questions in a list and load new questions on 'next' button press. When last question is displayed change the button text to 'finish' and load new activity on pressing 'finish' with the correct answers' number in a bundle.
In your initial class you can add an extra to the intent:
int selectedId = rg.getCheckedRadioButtonId();
rb = (RadioButton) findViewById(selectedId);
Intent i = new Intent(MainActivity.this,Ques2.class);
i.putExtra("rb_value", rb.isChecked());
startActvity(i);
In your second class you can get the value of the extra that you passed:
this.getIntent().getExtras().getBoolean("rb_value");
If you need the results from Question One for Question Two, this would be the best method. If you do not need the results from Question 1 for Question Two, but you will need them for Results only, it might be best to look into SharedPreference (From memory, some expressions may be incorrect but close):
In your questions activities:
SharedPreferences sharedPreferences = this.getSharedPreferences("my.app.preferences", 0);
SharedPreferences.Editor sharedPreferences_edit = sharedPreferences.edit();
sharedPreferences_edit.putBoolean("question1", true);
sharedPreferences_edit.commit();
In your Results activity:
SharedPreferences sharedPreferences = this.getSharedPreferences("my.app.preferences", 0);
sharedPreferences.getBoolean("question1");
For loading questions like this, loading up new intents is NOT the best solution, as you will end up layering your app... If i were creating something like this, I would make it able to change the question without having to load up a whole new activity, and upon button press, it will just change the question on the screen while storing the response to a variable/sharedPreferences.
I'm taking Questions and Answers in String[].The TextView has questions and RadioButton has corresponding answers. If Start Button is clicked, first set of question and answers is displayed in Linear Layout1. If Next Button is clicked LinearLayout1 is replaced by next set of question with answers and again if Next Buttonis clicked next set of question has to be replaced and vice versa. Help me in writing code for Next Button
Note: Only LinearLayout 1 should be changed when clicking Next Button
code:
TextView tv;
RadioButton rb1, rb2;
Button bStart, bNext;
String question[] = { "Key Lime Pie is upcoming version",
"Android is Middleware", "Which is latest Android version?" };
String answerA[] = { "True", "False" };
String answerB[] = { "True", "False" };
String answerC[] = { "Android 4.2", "Android 5" };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ques);
tv = (TextView) findViewById(R.id.textView111);
rb1 = (RadioButton) findViewById(R.id.radioButton1);
rb2 = (RadioButton) findViewById(R.id.radioButton2);
bStart = (Button) findViewById(R.id.startExam);
bNext = (Button) findViewById(R.id.bNext);
bStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
tv.setText(question[0]);
rb1.setText(answerA[0]);
rb2.setText(answerA[1]);
}
});
bNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
tv.setText(question[1]);
rb1.setText(answerB[0]);
rb2.setText(answerB[1]);
}
});
}
This is a logic problem.
Merge all the answers into a multidimensional array.
Keep track of the current question.
Use the tracking variable to get the question title in question.
Use the tracking variable to get the answers in the multidimensional array of answers. This is the first dimension of the array.
You read the answers in that dimension and display them in rb1 and rb2.
By using what you have there you will have problems extending that code. After all, are you really going to create a new variable for each different set of answers? It does not make any sense. A multidimensional array works.
However... although you can improve your arrays structure and use an int to keep track of the current displayed question (and thus increment it to get the next question after pressing the bNext), I suggest you try to create more meaningful objects, like a Question class, with relevant members (title, optionA, optionB, whatever...), especially because it looks like you're using this code to learn how to program a quiz-styled application.
Then you can create various questions and iterate through then.
But is that the issue there? No. The problem is keeping track of questions and answers. Use a multidimensional array with a tracking variable.
// edited: OK, I'm going to suggest something very quick for you:
static String[] questions = new String[] { "Question 1", "Question 2", "Question 3" };
static String[][] answers = new String[][] {
{"Answer 1.a", "Answer 1.b"},
{"Answer 2.a", "Answer 2.b"},
{"Answer 3.a", "Answer 3.b"},
};
int pos = -1;
void showNextAnswer() {
pos++;
tv.setText(questions[pos]);
rb1.setText(answers[pos][0]);
rb2.setText(answers[pos][1]);
}
bStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showNextAnswer();
}
});
bNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showNextAnswer();
}
});
As you can, both buttons do the same thing, so it's probably better to only use a next button.
Create a single array for answers. And declare tracking variables for questions and answers as:
String answer[] = {"True", "False" , "True", "False",
"Android 4.2", "Android 5" };
int current = 0; // this is your new variable
int ans = 1; // this is initialized to 1, because
// I assumed your first question and answer
// is displayed with the press of start button
Change your next button listener to this
public void onClick(View v) {
current ++;
if(current < question.length){
tv.setText(question[current]);
rb1.setText(answer[ans+=1]);
rb2.setText(answer[ans+=1]);
}
}
I want to create an application based on quiz which consists of 14 questions.
Can anyone tell me how do I need to go from one question to another by clicking on next button.If I use an Intent then I am afraid that I will be creating 14 Activities :(
I don't think that is the programmatic procedure too.
You can stay in the same Activity and keep track of the question.
You might want to use a TextSwitcher to add a fade in/fade out animation when swapping the question's text.
You could have the button click just update the questions text to be the next question.
nextButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
questionTextView.setText(questionTwo);
}
});
#Vivek you can use view flipper
this might help you
http://www.bogotobogo.com/Android/android9TabWidgetFlipper.html#SlidingDrawer
http://www.warriorpoint.com/blog/2009/05/29/android-switching-screens-by-dragging-over-the-touch-screen/
Change the text of your textviews where the questions are.
#Override
protected void onCreate(Bundle savedInstanceState) {
Button nextButton = (Button) findViewById(R.id.yourButtonId);
TextView questionTextView = (TextView) findViewById(R.id.yourTextViewId);
nextButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
questionTextView.setText("Your Next Question");
}
});
}
A Fragment is a piece of an application's user interface or behavior that can be placed in an Activity.
Has its own lifecycle;
Receives its own input events;
Can be added or removed while the activity is running;
Believe me that is the best method. I have been introduced to fragments having an application with quotes. The list of the quotes in left and the quotes that were changing on left when an author have been selected.
I'm using android.widget.ViewFlipper that contains views where one view contains TextView (question) and "input control" for answer (selectboxes, date/time widget, radiogroup, etc).