Using #OnCheckedChanged (ButterKnife) with radioGroup gives error in android - android

i recently integrated butterknife in my android project, and now i am trying to use #OnCheckedChanged annotation for radiogroup. but getting error of not giving callback. So what is the right method to call and get checkedId or this one is for radiobutton only and not for radiogroup.
#OnCheckedChanged(R.id.gendergroupid)
void onGenderSelected(RadioGroup group, int checkedId){
switch(checkedId){
case R.id.maleid:
maleid.setEnabled(true);
maleid.setChecked(true);
break;
case R.id.femaleid:
femaleid.setEnabled(true);
femaleid.setChecked(true);
break;
case R.id.bothid:
bothid.setEnabled(true);
bothid.setChecked(true);
break;
}
}
Gives me error
BloError:(89, 10) error: Unable to match #OnCheckedChanged method arguments.
Parameter #1: android.widget.RadioGroup
did not match any listener parameters
Parameter #2: int
did not match any listener parameters
Methods may have up to 2 parameter(s):
android.widget.CompoundButton
boolean
These may be listed in any order but will be searched for from top to bottom.ckquote

According the specification, this annotation needs to be used with 2 parameters, a CompoundButton and a boolean, so if you really want to use this listener, you have to change it like this:
#OnCheckedChanged(R.id.gendergroupid)
void onGenderSelected(CompoundButton button, boolean checked) {
//do your stuff.
}
I think in your case this listener doesn't work, so you can use another implementation like:
#OnClick({R.id.radio_1, R.id.radio_2})
public void onRadioButtonClicked(RadioButton radioButton) {
// Is the button now checked?
boolean checked = radioButton.isChecked();
// Check which radio button was clicked
switch (radioButton.getId()) {
case R.id.radio_1:
if (checked) {
// 1 clicked
}
break;
case R.id.radio_2:
if (checked) {
// 2 clicked
}
break;
}
}

this worked for me
#OnCheckedChanged({R.id.radio_button1, R.id.radio_button2})
public void onRadioButtonCheckChanged(CompoundButton button, boolean checked) {
if(checked) {
switch (button.getId()) {
case R.id.radio_button1:
// do stuff
break;
case R.id.radio_button2:
// do stuff
break;
}
}
}

Related

How to storage previous clicked button?

I'm making a fragment of language game in which will be a matching of the word and the translation. I need to store the previously clicked button and after clicking on another button compare them, and if they match to make them invisible.
But I'm getting an error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.Button.getText()' on a null object reference
On the line String text = buf.getText().toString();
All buttons were defined before.
#Override
public void onClick(View v) {
if (button_prev != 9) {
if (v.getId() != button_prev) {
Button buf = (Button) v.findViewById(button_prev);
String text = buf.getText().toString();
if (book_array.indexOf(text) - book_array.indexOf((String) ((Button) v).getText()) != 0) {
// book_array obj contains word and translating
i--;
v.findViewById(v.getId()).setVisibility(View.INVISIBLE);
v.findViewById(button_prev).setVisibility(View.INVISIBLE);
}
}
}
switch (v.getId()) {
// Storage the previously clicked the button in button_prev
case R.id.button1:
button_prev = Button_1.getId();
// button_prev = R.id.button1;
break;
case R.id.button2:
button_prev = Button_2.getId();
break;
case R.id.button3:
button_prev = Button_3.getId();
break;
case R.id.button4:
button_prev = Button_4.getId();
break;
case R.id.button5:
button_prev = Button_5.getId();
break;
case R.id.button6:
button_prev = Button_6.getId();
break;
case R.id.button7:
button_prev = Button_7.getId();
break;
case R.id.button8:
button_prev = Button_8.getId();
break;
default:
break;
Maybe someone could fix the code? Is there any correct way to store clicked buttons ?
You can declare a POJO for lastclicked view like following to store lastClicked view.
public class LastViewClicked {
private View view;
public View getView() {
return view;
}
public void setView(View view) {
this.view = view;
}
}
Now to when you click on any button, update the view Object inside LastClickedView using setView Method and when you need to know what was the last clicked button, you create a switch statement with all Ids as cases and if it matches you can do your operation.
// This Function gets the last clicked item which has opened up the Alert Dialog for
// selection and Updates its UI...
private void UpdateLastClickedView(int position, ArrayAdapter arrayAdapter) {
View v = lastViewClicked.getView();
// cast according to your views...
AppCompatTextView appCompatTextView = (AppCompatTextView) v;
// do your operation...
switch(appCompatTextView.getId()){
case R.id.tv1:
// hide or whatever you want to do...
break;
case R.id.tv2:
// hide or whatever you want to do...
break;
}
}
Your null pointer error may be the result of fragment recreation, which results in the value of button_prev invalid. And, the initial value of button_prev may be the reason.
findViewById is a time consuming function. The view binding should be processed once, and once only, in onCreate()
It's better if using MVC, MVP or MVVM. User a model to describe your game logic. Focus on the data change, and the UI should be changed with it.
Declare button_prev as field in your activity or fragment and use getter and setter to access it inside onclick.

OnClick listener always shows same v.getId()

I am working on a simple login form with 4 kinds of users. The onclicklisteners view parameter always shows the same v.getId() value which was clicked first time. Eg if the student view is clicked,the id value if updated but if i click the admin layout, the id still stays same as student.This happens with all the 4 sections.
Listener:
#Override
public void onClick(View v) {
loginActivityBinding.etPassword.setText("");
loginActivityBinding.etUsername.setText("");
loginActivityBinding.etPassword.setOnFocusChangeListener((v1, hasFocus) -> {
if (!Utils.isValidPassword(loginActivityBinding.etPassword.toString())) {
showToast("Please enter a valid password");
}
});
alertDialog.setPositiveButton("Login", (dialog, which) -> {
if (StringUtils.isEmpty(loginActivityBinding.etUsername.getText().toString(), loginActivityBinding.etPassword.getText().toString())) {
showToast("Error .Please fill all fields");
} else {
Timber.d(String.valueOf(v.getId()));
switch (v.getId()) {
case R.id.ll_Admin:
mainLoginViewModel.login(loginActivityBinding.etUsername.getText().toString(), loginActivityBinding.etPassword.getText().toString(), 1);
break;
case R.id.ll_faculty:
mainLoginViewModel.login(loginActivityBinding.etUsername.getText().toString(), loginActivityBinding.etPassword.getText().toString(), 2);
break;
case R.id.ll_student:
mainLoginViewModel.login(loginActivityBinding.etUsername.getText().toString(), loginActivityBinding.etPassword.getText().toString(), 3);
break;
case R.id.counsellorlayout:
mainLoginViewModel.login(loginActivityBinding.etUsername.getText().toString(), loginActivityBinding.etPassword.getText().toString(), 4);
break;
}
}
});
}
The flag value passed to the viewmodel stays the same after the first click.
Fixed it by creating seperate click listeners using the setOnClickListener approach. bad approach surely but couldnt see any other way out.

Why does it used R.id.buttonX in onClick method instead of comparing view to exists buttons?

I have onClick method, for example, in Activity. Why it is a bad aproach to handle such way?
#Override
public void onClick(final View v) {
if (v == mBtnGo || v == mBtnBack) {
handleActionClick();
} else if (v == mBtnNext) {
handleNextClick();
}
}
Supposed to use this logic:
#Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.btn_go:
case R.id.btn_back:
handleActionClick();
break;
case R.id.btn_next:
handleNextClick();
break;
default:
break;
}
}
Both of the methods will work.
When dealing with multiple clicks inside a single onClick() method
the second method allows you to use a switch statement,
which is faster and far more readable than a chain of if-else statements.
Sometime we don't need keeping a reference of a View. We just want to register for click event like: findViewById(R.id.button).setOnClickListener()
And I also prefer using switch instead of if-else

Droid: How to get button id from onClick method described in XML?

Following the dev guide, I can add a method to a button using in the XML. This calls the 'buttonPress' method in my activity. If I apply the same method to multiple buttons, how can I determine the identity of the button that has been clicked?
Use getId() method. It returnes the int id that you can compare to the id from resources.
It is very convenient to use switch statement like this:
public void buttonPress(View v) {
switch (v.getId()) {
case R.id.button_one:
// do something
break;
case R.id.button_two:
// do something else
break;
case R.id.button_three:
// i'm lazy, do nothing
break;
}
}

So, why is my switch case affecting all the following cases?

So, I'm trying to set up a series of checkboxes that, when clicked, will add a number, depending on the checkbox to either the int variable attackTotal or damageTotal, which will in turn be shown in some textviews.
Currently, however, clicking the top checkbox acts as if I had clicked both it, and every checkbox after it in the switch statement. The second clickbox seems to activate itself and all the following ones as well, etcetera etcetera...
So here's the code I've gotten together.
public void onCheckboxClicked(View v) {
// Is the view now checked?
boolean checked = ((CheckBox) v).isChecked();
// Check which checkbox was clicked
switch(v.getId()) {
case R.id.checkBox1:
if (checked)
{
flankAttack=2;
}
else
{
flankAttack=0;
}
case R.id.checkBox2:
if (checked)
{
pbs=1;
}
else
{
pbs=0;
}
all the way down to..
case R.id.checkBox10:
if (checked)
{
attackTotal=attack+flankAttack+pbs;
damageTotal=damage+pbs;
TextView textView = (TextView) findViewById(R.id.textView2);
TextView textView2 = (TextView) findViewById(R.id.textView4);
textView.setText(Integer.toString(attackTotal));
textView2.setText(Integer.toString(damageTotal));
}
else
{
attackTotal=attack+flankAttack+pbs;
damageTotal=damage+pbs;
TextView textView = (TextView) findViewById(R.id.textView2);
TextView textView2 = (TextView) findViewById(R.id.textView4);
textView.setText(Integer.toString(attackTotal));
textView2.setText(Integer.toString(damageTotal));
}
I only started trying to figure out this programming stuff on Friday, so be gentle.
just before case R.id.checkBox2: you need to have a break; to tell the program to break from the switch statement. Otherwise anything meeting R.id.checkBox1 just continue through and executes all the logic you have for R.id.checkBox2 as well. (You need break; before all your other cases as well).
You forgot adding
break;
in the end of every case.
You forgot the break statement after each case. It is falling through to the next case each time.
Also, I strongly recommend not to put more than a few lines of code in a case statement, else it gets ugly very fast and hard to work with. Instead, pull out each case into its own method. Usually it will be easy to come up with a good name for each that is self-documenting:
switch (foo) {
case 0:
do();
lots();
of();
things();
break;
case 1:
do();
other();
things();
break;
case 2:
if (ugly)
{
this_gets();
messy();
quickly();
}
else
{
we_could();
do_better();
}
break;
}
Becomes:
void do_case_0() {
do();
lots();
of();
things();
}
void do_case_1() {
do();
other();
things();
}
void do_case_2() {
if (ugly)
{
this_gets();
messy();
quickly();
}
else
{
we_could();
do_better();
}
}
// ...
switch (foo) {
case 0: do_case_0(); break;
case 1: do_case_1(); break;
case 2: do_case_2(); break;
}

Categories

Resources