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;
}
}
Related
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.
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
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;
}
}
}
Instead of have to call separate method for each button, would it be possible to just use one method and check which button it was that was clicked by it's id?
I'm using the simple way like android:onClick="activateButtons"
public void activateButtons(View v)
{
if(?? == btn_1)
{
Code for button with ID = btn_1
}
if(?? == btn_1)
{
Code for button with ID = btn_2
}
}
You can do that if you tag the buttons with an Id. Set the android:id="#+id/yourbuttonid" in the xml file. Then do if(v.getId() == R.id.yourbuttonid) in the onClick method.
Yes it is possible. You can assign specific ids(eg: button1) for buttons and then call v.getId() in activateButtons(onclick method) to check if it is equal to R.id.button1 and then do your operation there.
Cheers,
Richie
public void onClickKeyPad(View view)
{
EditText text = (EditText)findViewById(R.id.text_password);
switch(view.getId())
{
case R.id.button_0:
text.setText(text.getText() + "0");
break;
case R.id.button_1:
text.setText(text.getText() + "1");
break;
case R.id.button_cancel:
finish();
break;
default:
break;
}
}
In my layout xml file I have set the android:onClick attribute for a Button element to a function in my activity. So when I click the button the function is called with a View as its argument. Are there any information in that View argument that has the id of the button being clicked? I'm trying to figure out if I have to have one onClick function for every element or if I can use one function and switch depending on the id of the element being clicked.
switch (v.getID) {
case R.id.A:
.....
}
ohh Apps has the answer all right... just for throughness I have something like so...
case sensitive stuff.... funny how a getID won't work while a getId will be golden... funny how a compiler couldn't do a "sloppy check" and correct such case issues.
like so
View myButton = findViewById(R.id.mybutton);
myButton.setOnClickListener(this);
View myOtherButton = findViewById(R.id.myotherbutton);
myOtherButton.setOnClickListener(this);
public void onClick(View v) {
switch (v.getId()) {
case R.id.mybutton:
//Do something related to the mybutton click
break;
case R.id.myotherbutton:
//Do something related to the myotherbutton click
break;
//chain all Resource ID's here like above....
}
}
you must also not to forget to setup a Onclick listener for every click event before the switch or the case will never get resolved....
//whoo hoo. 8cupsaday android app coming soon!