RadioGroup provide method "set()" for OnCheckedChangeListener, but not "get()". But my module must in some way get OnCheckedChangeListener of RadioGroup and wrap it with my listener, which provide tracking of behavior for customer. How can I get this OnCheckedChangeListener listener without asking user of my library to provide it explicitly as parameter?
Sample of problem:
we can implement method:
void wrapMyRadioGroup(RadioGroup group,OnCheckedChangeListener listener){
group.setOnCheckedChangeListener(new SomeCompositeListener(listener));
}
but can't some like this:
void wrapMyRadioGroup(RadioGroup group){
group.setOnCheckedChangeListener(new SomeCompositeListener(group.getOnCheckedChangeListener()));
}
And,as you can gues, we need last one.
P.S.
I've found solution with reflection.
private void trackRadioGroup(RadioGroup radioGroup){
RadioGroup.OnCheckedChangeListener listener = null;
try {
Field field = radioGroup.getClass().getDeclaredField("mOnCheckedChangeListener");
field.setAccessible(true);
Object value = field.get(radioGroup);
if(value !=null){
listener = (RadioGroup.OnCheckedChangeListener)value;
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
radioGroup.setOnCheckedChangeListener(new SomeCompositeListener(listener));
}
Thanks all for understanding and rates...
try this
RadioGroup radioGroup = (RadioGroup)findViewById(R.id.cancle_booking_radio_group);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
View radioButton = radioGroup.findViewById(checkedId);
int index = radioGroup.indexOfChild(radioButton);
switch (index) {
case 0:
// perform your action here
break;
case 1:
// perform your action here
break;
case 2:
// perform your action here
break;
case 3:
// perform your action here
break;
case 4:
// perform your action here
break;
}
}
});
Related
I'm new to android, I have a button that is when its clicked it will get the double value from an EditText and show it in a TextView.
Also I have two radio buttons, one is positive and other is negative, I want when the user toggle the negative button to multiply the double by -1, my code is like:
public void buttonClicked(View view) {
try {
myDouble = Double.parseDouble((myDoubleEditText.getText().toString()));
} catch (NumberFormatException e) {
Toast.makeText(getApplicationContext(), "Enter a valid Double", LENGTH_LONG).show();
}
myTextView.setText("My Double is",""+myDouble)
}
public void onRadioButtonClicked(View view) {
boolean checked = ((RadioButton) view).isChecked();
switch(view.getId()) {
case R.id.positive:
if (checked)
myDouble = myDouble;
break;
case R.id.negative:
if (checked)
myDouble = myDouble * -1;
break;
}
}
}
Please guide me to do it.
Thanks
I'd think a better way is to use RadioGroup and set the listener on this to change and update the View accordingly (saves you having 2 or 3 or 4 etc listeners).
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.yourRadioGroup);
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// checkedId is the RadioButton selected
switch(checkedId) {
case R.id.positive:
myDouble = myDouble;
break;
case R.id.negative:
myDouble = myDouble * -1;
break;
}
}
});
I want to do an Android App Quiz. I did a radiogroup with 4 radiobuttons that represent the 4 answers.
I want that when these radiobuttons aren't clicked the app shows an error, but my doesn't do it.
This my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
RadioGroup champ=(RadioGroup)findViewById(R.id.answer1);
champ.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#SuppressWarnings("null")
public void onCheckedChanged(RadioGroup group, int checkedId) {
// TODO Auto-generated method stub
switch(checkedId) {
case R.id.answer1A:
ans1 =0;
break;
case R.id.answer1B:
ans1 =1;
break;
case R.id.answer1C:
ans1 =2;
break;
case R.id.answer1D:
ans1 =3;
break;
case R.id.answer1E:
ans1 =4;
break;
default:
ans1=(Integer) null;
Toast.makeText(MainActivity.this, "error", Toast.LENGTH_LONG).show();
break;
}
}
});
Why?Can you help me, please?
First assign:
ans1=-1; //in onCreate or at the time of declaration
You might be having a button or something clicking on which you would be accessing which answer was checked, there you can check :
if(ans1==-1)
{
//show error message
}
else
{
//Success
}
This check is not executing because this is a checkedchangelistener which will trigger when you click on some radiobutton (when status is changed).
All you have to do is Check the status of the each and every radiobutton outside this listener.
I have an Activity which implements both Checkbox.OnCheckedChangeListener and RadioGroup.OnCheckedChangeListener The groups are both dynamically generated and passed the same Activity as the listener.
However, when I click on a RadioGroup, the RadioGroup.OnCheckChangeListener is completely ignored but here's where it gets weird. It triggers CheckBox.OnCheckChangeListener! I tried casting the activity to the RadioGroup listener before passing it, but RadioGroup cannot even accept it, only the CheckBox listener gets through.
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(subquestion.getQuestionType().equals("MULTIPLE_CHOICE_MULTI_ANSWER")) {
String selected = buttonView.getText().toString();
if (subquestion.getAnswer().getDataList() != null) {
Answer answer = subquestion.getAnswer();
ArrayList<String> checked = answer.getDataList();
if (checked.contains(selected)) {
checked.remove(selected);
Log.d("Checkbox" + buttonView.getId(), "unchecked");
} else {
checked.add(selected);
Log.d("Checkbox" + buttonView.getId(), "checked");
}
} else {
ArrayList<String> checked = new ArrayList<String>();
checked.add(selected);
subquestion.getAnswer().setDataList(checked);
Log.d("Checkbox" + buttonView.getId(), "checked");
}
}
if(subquestion.getQuestionType().equals("MULTIPLE_CHOICE_SINGLE_ANSWER")) {
RadioGroup group = buttonView; //CAN'T BE DONE
String selected = group.getFocusedChild().getId() + "";
subquestion.getAnswer().setData(selected);
Log.d("Radiobutton " + selected + group.getFocusedChild().getId(), "selected");
}
}
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//This does NOTHING, can't even be passed to the RadioGroup as a listener
}
How do I get the RadioGroup from the buttonView? I generate everything in code and it's different every time so there are no static id's to determine what's clicked. I pass an id to the radiobuttons to let me know which is which but I can't get to it like this.
It works perfectly for the checkboxes, it's just that Android seems to throw the wrong event and uses the wrong event handler for RadioGroup.
Thank you for reading!
Call this method for RadioGroup.OnCheckChangeListener and pass RadioGroup as argument
public void onRadioChangeListener(RadioGroup radioGroup){
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// write your code here
}
});
}
I'm creating quiz app, and when the user selects an answer, I will change the background color of the Radio Button based on whether he/she was correct/incorrect. I want to do this and pause at this part for a second or two, then change the questions/answers in my fragment. The problem is, I'm confused about where I should be putting the pause. Normally, I should put the pause right before the onAnswerSelected() function (changes the text on my RadioButtons) is executed. However, the problem with that is nothing on the screen will update until onCheckedChanged() has finished executing.
Fragment.java
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
List<String> answers = new ArrayList<String>();
answers.add(answer1);
answers.add(answer2);
answers.add(answer3);
answers.add(answer4);
Collections.shuffle(answers);
TextView questionTV = (TextView) getView().findViewById(R.id.question);
questionTV.setText(question);
final RadioButton answer1RB = (RadioButton) getView().findViewById(R.id.answer1);
final RadioButton answer2RB = (RadioButton) getView().findViewById(R.id.answer2);
final RadioButton answer3RB = (RadioButton) getView().findViewById(R.id.answer3);
final RadioButton answer4RB = (RadioButton) getView().findViewById(R.id.answer4);
answer1RB.setText(answers.get(0));
answer2RB.setText(answers.get(1));
answer3RB.setText(answers.get(2));
answer4RB.setText(answers.get(3));
answer1RB.setChecked(false);
RadioGroup rg = (RadioGroup) getView().findViewById(R.id.answers);
rg.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(RadioGroup group, int checkedId)
{
boolean correctAnswerSelected = false;
switch(checkedId)
{
case R.id.answer1:
if (answer1RB.getText().equals(answer1)) {
answer1RB.setBackgroundColor(Color.GREEN);
correctAnswerSelected = true;
} else {
answer1RB.setBackgroundColor(Color.RED);
findCorrectAnswer(answer1RB, answer2RB, answer3RB, answer4RB);
}
break;
case R.id.answer2:
if (answer2RB.getText().equals(answer1)) {
answer2RB.setBackgroundColor(Color.GREEN);
correctAnswerSelected = true;
} else {
answer2RB.setBackgroundColor(Color.RED);
findCorrectAnswer(answer1RB, answer2RB, answer3RB, answer4RB);
}
break;
case R.id.answer3:
if (answer3RB.getText().equals(answer1)) {
answer3RB.setBackgroundColor(Color.GREEN);
correctAnswerSelected = true;
} else {
answer3RB.setBackgroundColor(Color.RED);
findCorrectAnswer(answer1RB, answer2RB, answer3RB, answer4RB);
}
break;
case R.id.answer4:
if (answer4RB.getText().equals(answer1)) {
answer4RB.setBackgroundColor(Color.GREEN);
correctAnswerSelected = true;
} else {
answer4RB.setBackgroundColor(Color.RED);
findCorrectAnswer(answer1RB, answer2RB, answer3RB, answer4RB);
}
break;
}
// Need to execute some sort of pause here, and finish before onAnswerSelected is called
mCallback.onAnswerSelected(correctAnswerSelected);
}
});
}
QuizTemplate.java
#Override
public void onAnswerSelected(boolean answeredQuestionCorrectly) {
PlaceholderFragment fragment = (PlaceholderFragment)getSupportFragmentManager().
findFragmentById(R.id.container2);
if (fragment != null) {
RadioButton answer1 = (RadioButton) fragment.getView().findViewById(R.id.answer1);
RadioButton answer2 = (RadioButton) fragment.getView().findViewById(R.id.answer2);
RadioButton answer3 = (RadioButton) fragment.getView().findViewById(R.id.answer3);
RadioButton answer4 = (RadioButton) fragment.getView().findViewById(R.id.answer4);
answer1.setText("test");
answer2.setText("test");
answer3.setText("test");
answer4.setText("test");
answer1.setBackgroundColor(Color.WHITE);
answer2.setBackgroundColor(Color.WHITE);
answer3.setBackgroundColor(Color.WHITE);
answer4.setBackgroundColor(Color.WHITE);
answer1.setChecked(false);
answer2.setChecked(false);
answer3.setChecked(false);
answer4.setChecked(false);
}
Use thread and runnable. Sleep thread to pause and then update UI.
Sample Code:
new Thread(new Runnable() {
#Override
public void run() {
try {
//pause for 5 seconds
Thread.sleep(1000*5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// update your UI here
mCallback.onAnswerSelected(correctAnswerSelected);
}
});
}
}).start();
I have 10 buttons set up which are the answers to ten questions. When a certain button is clicked, I have a switch statement set up in my onClick method shown below. My question is what is the best way to set up the OnClickListeners for all the buttons seeing that I need to pass 2 arrays to the onClick method in order to tell if it is correct or not? Also, I need to return and integer value. Thanks
public void onClick(View v, int[] qaarray, int questionorder) {
int x=0;
switch(v.getId())
{
case R.id.imageButton0:
if(qaarray[0] == questionorder){
//correct
}else{
//incorrect
}
break;
case R.id.imageButton1:
if(qaarray[1] == questionorder){
// correct
}else{
//incorrect
}
break;
case R.id.imageButton2:
if(qaarray[2] == questionorder){
// correct
}else{
//incorrect
}
break;
case R.id.imageButton3:
if(qaarray[3] == questionorder){
// correct
}else{
//incorrect
}
break;
case R.id.imageButton4:
if(qaarray[4] == questionorder){
//correct
}else{
//incorrect
}
break;
case R.id.imageButton5:
if(qaarray[5] == questionorder){
//correct
}else{
//incorrect
}
break;
case R.id.imageButton6:
if(qaarray[6] == questionorder){
//correct
}else{
//incorrect
}
break;
case R.id.imageButton7:
if(qaarray[7] == questionorder){
//correct
}else{
//incorrect
}
break;
case R.id.imageButton8:
if(qaarray[8] == questionorder){
//correct
}else{
//incorrect
}
break;
case R.id.imageButton9:
if(qaarray[9] == questionorder){
//correct
}else{
//incorrect
}
break;
default:
throw new RuntimeException("Unknown button ID");
}
}
The OnClickListener only gives you one parameter, which is the View:
void onClick(View v);
But you don't have to pass the questions and 'order' to the method to have what you want. One of the technique you can use is the setTag() method of View:
int[] button = new int[] { R.id.imageButton1, R.id.imageButton2.... };
private class AnswerPair{
public int questionOrder;
public int answer;
}
public void onCreate(Bundle bundle){
for(int i=0; i<NO_OF_BUTTON; i++){
AnswerPair ans = new AnswerPair();
ans.questionOrder = i;
ans.answer = 0; // SET this
getViewById(button[i]).setTag(ans);
getViewById(button[i]).setOnClickListener(this);
}
}
public void onClick(View v){
if (v.getTag() == null) return;
try{
AnswerPair answer = (ans)v.getTag();
// Check answer == question order? index?
}catch(exception e) return;
}
You can implement as many OnClickListeners as you want and assign different listeners for each button.
public void onCreate(Bundle bundle){
setContentView(R.layout.main);
Button b = (Button) findViewById(R.id.myButton)
b.setOnClickListener(new MyListener());
}
private class MyListener implements OnClickListener {
#Override
public void onClick(View v) {
// Your code here
}
}
i think a lot of people know this already, but there's a shortcut you can use instead of having different instances of onClickListeners and assigning them in code using setOnClickListener(x).
In your button XML, give it the android:onClick property, and assign it a string you like, for example,
android:onClick="clickOne"
In the activity the sets this xml as its content view, create a method named clickOne with a View parameter.
public void clickOne(View view)
Whatever you place on this method will be executed when you click the button.