Button not responding to click event - android

Below is what i have tried. "Forward" class extends Activity. It contains two buttons. In this class , we create two objects of "Collector" class using for loop. In the first iteration of the loop we create first button. In the second, we create one more button. we set "OnClickListener" for both the buttons. but only the second button responds for the click. First button doesnt respond to a click. I'm trying to use same variable name (b1) - I want to stick to OO Principle by not creating separate object for achieving my goal. - Also I'm expecting properties of 2 Objects as separate entity.Please help me. regards.
Forward.java (is an Activity, contains two buttons):
below is a for loop in which i create 2 objects of collector class.
for (int i = 0; i < 2; i++) {
new Collector(this, i);
}
Collector.java :
public class Collector {
Forwarder f;
int n;
Button b1;
public Collector(Forwarder caller, int i) {
f = caller;
n = i; // 0 or 1
f.setContentView(R.layout.forwarder);
switch(n)
{
case 0:
b1 = (Button) f.findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// get a new Contact
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
f.startActivityForResult(i, 1);
// onActivityResult has to be implemented in f because
// f extends Activity class
}
});
break;
case 1:
b1 = (Button) f.findViewById(R.id.button2);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// get a new Contact
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
f.startActivityForResult(i, 1);
}
});
break;
default:
}
}
}

You gave Your button a new id.
first, You wrote:
b1 = (Button) f.findViewById(R.id.button1);
at the second switch You wrote:
b1 = (Button) f.findViewById(R.id.button2);

public class Collector {
Forwarder f;
int n;
Button b1;
public Collector(Forwarder caller, int i) {
f = caller;
n = i; // 0 or 1
f.setContentView(R.layout.forwarder);
switch(n)
{
case 0:
b1 = (Button) f.findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// get a new Contact
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
f.startActivityForResult(i, 1);
// onActivityResult has to be implemented in f because
// f extends Activity class
}
});
break;
case 1:
b1 = (Button) f.findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// get a new Contact
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
f.startActivityForResult(i, 1);
}
});
break;
default:
}
}
}

You have mistaken in your switch case you named both of buttons b1 when the second object starts to be create b1 is no longer Button1 now it is Button2 so you set onclick listener only for Button2 use a custom class for your buttons or try to declear new objects like b2 b3
good luck soheil

Check the button names. They are the same (b1). Change the second variable name and everything should work perfectly. Damn copy-paste :P

I don't have the answer on why such behavior but it will definitively help you if you add few things as a part of clarification or rephrase your question else people consider it as some novice mistake.
- Clearly mention that you know that you are trying to use same variable name (b1)
- You want to stick to OO Principle by not creating separate object for achieving your goal.
- Also you can mention that you are expecting properties of 2 Objects as separate entity.
Hope it helps. All the best.

Related

Android: set one Button to do several things

Can anyone help me? I'm stuck on this thing for about week. I want to set one button to do several things. For example: when I pressed button once - b1.setBackgroundResource(R.drawable.a), when I pressed twice - b1.setBackgroundResource(R.drawable.b), when pressed third - b1.setBackgroundResource(R.drawable.c) and so on. It is possible to do this? Very thanks!
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = (Button) findViewById(R.id.button);
b1.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
}
}
);
}
Have an int counter defined. In the onClick increment it and do whatever you want based on it's value
Yes it is possible
use button property known as setTag and getTag. It work same as that of flag
Example:
b1.setTag("1");
b1.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
if b1.getTag().equals("1"){
b1.setTag("2")
}
else if(b1.getTag().equals("2")) {}
}
}
);
I found a recent tutorial, detailing and explaining how to do what you want but it is accomplished using a short and long button press.
Try this: https://www.youtube.com/watch?v=cUgL8b7M8ns
Hope it helps.
Create a global variable
private int index = 0;
Then in your code do this
b1.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
switch (index) {
case 0:
firstFunction();
break;
case 1:
secondFunction();
break;
}
// Advance your counter and extract the %
index++;
index = index % numOfDifferentFunctions;
}
}
);

How do I load multiple buttons in at the same time?

I wanted to avoid answering this question and figure it out myself but after an entire afternoon wasted, here I am. I am trying to load 3 buttons when my app starts up. I tried using multiple startActivities but only one would load at a time and I am not sure why. I also tried using AsyncTasks but they seemed overly complex for what I was trying to do. For example, one of buttons was going to open the Google Maps application. I already have the code and had that working but I want one button that does that and 2 other buttons that do different things.
You're going to have to use an AsyncTask like this:
When you click the button it will execute the AsyncTask:
public void ThirtySecVideoPlayer(){
ThirtySecondImageButton = (ImageButton)findViewById(R.id.ThirtySecAdImageButton);
ThirtySecondImageButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
String Category = "Cleaninig";
String ProductUploadMethod = "ProductUploadMethod";
ProductUpload ProductUpload = new ProductUpload();
ProductUpload.execute(ProductUploadMethod, Category);
}
}
);
}
Then in your AsyncTask you get the params and us it in the AsyncTask:
private class ProductUpload extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
String Category = params[1];
}
#Override
protected void onPostExecute (String result){
}
}
#Override
protected void onProgressUpdate (Void...values){
}
}
You can use the button code for each button and then call the same AsyncTask, but you need to make sure that the variable category executes the correct code in the DoInBackround with an If statement!
You can create the button dynamically in your onCreate method.
// this is the text to put in the created button
String[] btnText = ["Button 1", "Button 2","Button 3"];
// the ID allows to determine witch button was pressed
int btnID = 0;
// in the for web be created the 3 button dynamically
for(int i = 0; i<3; i++){
final Button Btn = new Button(this);
Btn.setText(btnText[]);
//This is to give the button the size he need to wrap the text in it
LinearLayout.LayoutParams LayoutParams = new LinearLayout.LayoutParams(LayoutParams.wrap_content, LayoutParams.wrap_content);
Btn.setLayoutParams(LayoutParams);
Btn.setId(btnID);
btnID ++;
Btn.setOnClickListener(new OnClickListener(){
//This returns the Id of the clicked button
// the Id of each button was set by the "Btn.setId(btnID);"
DetectclickedButton(Btn.getId());
});
}
public void DetectclickedButton(id){
switch(id){
case 1:
// Do something in the click of the 1 button
break;
case 2:
// Do something in the click of the 2 button
break;
case 3:
// Do something in the click of the 3 button
break;
}
}

Retrieving information from custom dialog called from within non-Activity class

I am working on a board game app (similar to chess). I have the activity GameBoardActivity which listens for clicks on a GridView, and at each click calls functions from a class Game to handle what should occur.
Within the class Game is the data about where pieces are and the method Move(int xFrom, int yFrom, int xTo, int yTo) where piece movement is handled.
For certain movements that a user may specify (e.g. that the piece at xFrom, yFrom should go to xTo, yTo) I want to provide them with a choice between two options. You can imagine that one choice is to go there normally, and the other is to go there as a transformed piece. To do this I want to display a custom dialog that presents the two choices for the user to click.
My custom Dialog class is given below:
public class CustomDialog extends Dialog implements View.OnClickListener{
Context mcontext;
Button button1;
Button button2;
int choice; //holds value of user's choice
public CustomDialog(Context context) {
super(context);
mcontext = context;
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
choice = 0; //no choice yet
}
public void setLayout(){
this.setContentView(R.layout.custom_dialog);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
choice = 1;
break;
case R.id.button2:
choice = 2;
break;
}
dismiss();
}
}
What I'm not clear on is how to pass the information about the user's choice back to the class Game.
Any help is greatly appreciated.
Save a reference to parent Activity via the constructor of the dialog:
private final MyActivity mCaller;
public CustomDialog(MyActivity caller) {
super(caller);
mCaller = caller;
//.......
}
Pass values to calling activity by invoking its methods:
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
mCaller.setChoice(1);
break;
case R.id.button2:
mCaller.setChoice(2);
break;
}
dismiss();
}
Create a bean class for storing the button actions ....
While clicking the events store it in a bean
In a game class u access the action values for button from the bean class

Keeping multiple OnClickListeners in one class

I am kinda new to Android and it would improve my application a lof if I coul keep several OnClickListenres in one class. What I am thiking of is something like this :
Public class OnClickListeners {
public Button.OnClickListener open;
public Button.OnClickListener doSomethingElse;
public Button.OnClickListener etc;
public OnClickListeners() {
open = new Button.OnClickListener()
{
public void onClick(View view)
{
DetailList.SetId(view.getId());
Intent intent = new Intent(view.getContext(), DetailList.class);
startActivityForResult(intent, 100);
}
};
}
}
So I can then reference it in other class B like this
button1.setOnClickListener(OnClickListeners.open);
Any though how to do it?
Android SDK seems to be against me as I can figure it out now for about 2 days now...
Thanks for any advices and help
There is a sleek way to consolidate all your anonymous classes into one and switch on the view. This works best if you know ahead of time which buttons will be using the clicklistener :
public class AndroidTestClickListenerActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new MyClickListener());
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new MyClickListener());
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new MyClickListener());
}
}
class MyClickListener implements View.OnClickListener {
#Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.button1:
// do soemthign for button1
break;
case R.id.button2:
// do something for button2
break;
case R.id.button3:
// do something for button3
break;
default:
// do something for any other button
}
}
}
You can write
button1.setOnClickListener(new OnClickListeners().open);
instead, but this seems an odd architecture for me. I'd suggest you to keep 1 listener in 1 file, having all of them in 1 package, and use like
button1.setOnClickListener(new OpenListener());
The problem of you approach is that usually listeners have to manipulate some data that is part of the class where UI elements are.
If you take listeners out and put them in a separate class, you will also have to provide a lot of references to objects where data to be manipulated is. This will create a lot of interdependent classes, which will not be nice.
IMHO the cleanest way is to use anonymous inner classes.
You can, but you have to declare the OnClickListener as static if you would like to use it in this manner.
public static Button.OnClickListener openListener = new Button.OnClickListener() {
public void onClick(View view) {
}
};
Then you can use:
button1.setOnClickListener(OnClickListeners.openListener);
As noted by other user - this approach is most like bad. You should handle view listeners on the same view and then maybe call another method like openActivity(). I would not do this - you are also openning an activity from another activity, this will probably don't work at all or will mess up the activity history stack
As none of the solutions actually did what I wanted to achieve - I needed a second (or multiple) onClickListener that did not override the onClickListeners that were already assigned to the control.
Here is the java class that I wrote for that purpose:
https://gist.github.com/kosiara/c090dcd684ec6fb2ac42#file-doubleclicklistenerimagebutton-java
public class DoubleClickListenerImageButton extends ImageButton {
View.OnClickListener mSecondOnClickListener;
public DoubleClickListenerImageButton(Context context) {
super(context);
}
[...]
public void setSecondOnClickListener(View.OnClickListener l) {
mSecondOnClickListener = l;
}
#Override
public boolean performClick() {
if (mSecondOnClickListener != null)
mSecondOnClickListener.onClick(this);
return super.performClick();
}
#Override
public boolean performContextClick() {
if (mSecondOnClickListener != null)
mSecondOnClickListener.onClick(this);
return super.performContextClick();
}
}

Dynamically creating Buttons and setting onClickListener

I have problem with handling dynamically created Buttons on Android. I'm creating N buttons and I have to do the same method when button is clicked but I have to know which button is clicked.
for (int i = 0; i < NO_BUTTONS; i++){
Button btn = new Button(this);
btn.setId(2000+i);
...
btn.setOnClickListener((OnClickListener) this);
buttonList.addView(btn);
list.add(btn);
Cucurrently I'm adding ID to every button and I'm using the method below to see which button was clicked. (line btn.setId(2000+i); and btn.setOnClickListener((OnClickListener) this);). This method is also implemented in the activity.
#Override
public void onClick(View v) {
switch (v.getId()){
case 2000: selectButton(0);
break;
...
case 2007: selectButton(7);
break;
}
}
This doesn't look good to me so i'm asking is there some better way to do this? or how to send some information to onclick event? any suggestions?
You could create a method that returns an onclickListener and takes a button as a parameter. And then use that method to set the onClicklistener in the first loop you have..
Update: code could be soemthing along these lines:
View.OnClickListener getOnClickDoSomething(final Button button) {
return new View.OnClickListener() {
public void onClick(View v) {
button.setText("text now set.. ");
}
};
}
as a method in the activity and then use it in the loop like this
button.setOnClickListener(getOnClickDoSomething(button));
I got one solution for this..
use this code in onCreate
linear = (LinearLayout) findViewById(R.id.linear);
LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f);
Button[] btn = new Button[num_array_name.length];
for (int i = 0; i < num_array_name.length; i++) {
btn[i] = new Button(getApplicationContext());
btn[i].setText(num_array_name[i].toString());
btn[i].setTextColor(Color.parseColor("#000000"));
btn[i].setTextSize(20);
btn[i].setHeight(100);
btn[i].setLayoutParams(param);
btn[i].setPadding(15, 5, 15, 5);
linear.addView(btn[i]);
btn[i].setOnClickListener(handleOnClick(btn[i]));
}
after onCreate create one method of return type View.OnClickListener like this..
View.OnClickListener handleOnClick(final Button button) {
return new View.OnClickListener() {
public void onClick(View v) {
}
};
}
Button.OnClickListener btnclick = new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Button button = (Button)v;
Toast.makeText(getApplicationContext(), button.getText().toString(),2).show();
}
};
call this listener by btn.setOnClickListener(btnclick);
View IDs should not be used for these purposes as View Ids are generated on compilation time depending on IDs defined in xml layout files.
Just place your own IDs in the setTag() method which is available at the View level (so Buttons inherit them). This "tag" can be anything that allow you to recognize a View from others. You retrieve its value with getTag().
instead use setTag() function to distinct easily.
for(int i=0;i<4;i++) {
Button btn = new Button(this);
btn.setTag(i);
btn.setOnClickListener(new View.OnclickListener() {
#Override
public void onClick(View v) {
int i=v.getTag();
switch(i) {
case 1: btn.setText(i);
break;
case 2: btn.setText(i);
break;
case 3: btn.setText(i);
break;
case 4: btn.setText(i);
break;
default: btn.setText("Others");
}
}
}
"This doesn't look good to me" why not? doesn't it work? You could also create a static member variable holding a list of all added buttons, and then look for the clicked button in that list instead.
I don't know why you would want to create N buttons, it looks like your value of N is greater than 10 at least, if you are not trying to show them all at once (I mean fit all of them into one single screen, no scrolling) you could try to recycle the invisible buttons just like we do for list view using a list view holder. This would reduce your memory footprint and boost performance, and differentiate the buttons based either on the text you set on them or a tag or you can even hold a reference to those small number of buttons.
Is preferable not to mess up with the ids, setTag and getTag methods were designed for that purpose, it's the fast and clean way to set a bunch of button listeners on a dynamic layout
This answer may you help:
https://stackoverflow.com/a/5291891/2804001
public class MainActivity extends Activity implements View.OnClickListener
{
LinearLayout linearLayout;
Button [] button;
View.OnClickListener listener;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout=(LinearLayout)findViewById(R.id.parent_lay);
String[] array={"U123","U124","U125"};
int length=array.length;
System.out.println("11111111111111111111111111");
button=new Button[length];
for(int i=0;i<length;i++)
{
button[i]=new Button(getApplicationContext());
button[i].setId(i);
button[i].setText("User" + i);
button[i].setOnClickListener(this);
linearLayout.addView(button[i]);
}
}
#Override
public void onClick(View view)
{
view.getId();
Button button=(Button)findViewById(view.getId());
button.setText("Changed");
}
}

Categories

Resources