Set Onclick on many views Android - android

I have a serie of ImageViews on my Activity. And I wanna execute a method when one of these is touched. I have the next:
public void onClick(View v) {
switch(v.getId()){
case R.id.image1:
mymethod(1,1,movimientos,(ImageView)v);
break;
case R.id.image2:
ponerficha(1,2,movimientos,(ImageView)v);
break;
case R.id.image3:
...
But the method isn't executed, The problem not is the method, because any code in the cases not work. Any idea?

First thing what you need to check if you already register onClickListener for your Images
image.setOnClickListener(this);
(This you have to use if your class implements OnClickListener interface)
Then how you declare and initialize your ImageViews, whether have own ids.
image = (ImageView) findViewById(R.id.someId)
anotherImage = (ImageView) findViewById(R.id.anotherId)
...
You can work with onClickListeners like with anonyme classes like
image.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// some actions
}
});
but more complex and better in the case you have many widgets to set implement OnClickListener.
public class ClassName extends Activity implements View.OnClickListener {}

First, your activity has to implement View.OnClickListener like so
public class myActivity implements View.OnClickListener {
Then you need to set your on click listener for your ImageViews. If all your ImageViews are in a linearlayout then the code would look like this
LinearLayout llImageViewHolder = (LinearLayout) findViewById(R.id.llImageViewHolder);
for (int i = 0; i < llImageViewHolder.getChildCount(); i++ {
ImageView iv = (ImageView) llImageViewHolder.getChildAt(i);
iv.setOnClickListener(this);
}
Cheers.

You need to add an onClick handler to each view you are interested in processing clicks for.
How you do it depends on how you want to process the click events. You can either use hawaii.five-0's approach and have one event handler for everything, or you can have one event handler per view item which you could add in the onCreate method of your activity:
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// Do something
}
}

Related

Defining OnClickListener separately or inside setOnClickListener()?

I was filling inside a getView() of an adapter while defining the click listeners, this got me wondering:
Performance-wise, is there a difference between these two implementations:
Defining onClickListener separately:
View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) { //... }
};
mView.setOnClickListener(mClickListener);
and
Defining onClickListener as the argument:
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //... }
});
As getView() is frequently called, my though is that even small differences in its implementation would have big effect in app's performance. But I'm not sure.
So, which of the above is recommended regarding the performance/memory? Or aren't they that different to matter?
Well that actually depends on how many OnClickListeners do you have as anonymous classes.
it would be better to implement one click listener and set it to all of the views on which you want to get click event and sort the clicks out with view id's in OnClick(View v)
public void onClick(View v) {
switch (v.getId()) {
case R.id.some_view_id:
doSomething();
break;
}
}

Runtime onClicklLstener android

Just wondering can anyone solve this problem about adding listeners to imagebuttons at runtime. I'm presuming it has got something to do with the "this" parameter passed to setOnClickListener as we are already in a onClickListener.
My fragment implements onclicklistener. The onClick methods work for imagebuttons known at compile time, just not for the ones that are defined after inflating a prompt view. What seems to happen is the prompt layout seems to be recreated and added onto the back stack.
Basically the onclicklistener for mWhatsappshare,mEmail share does not react as I might expect. I put a stackoverflow error in the onclick method previously and when I clicked these imagebuttons my application did not crash. This means that the listener is in fact not registered (or at least not correctly) at
mwhatsapp.setonclicklistener(this)
By the way, I do not want to set separate listener like mWhatsapp.setonclicklistner(new View.onClickListener()){ for each imagebutton as it is too cumbersome and I want each listener to be handled in onclick().
Thank you
mOtherShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeColorFilters();
mOtherShare.setImageResource(R.drawable.other_pill_pressed);
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.share_prompt,null);
mWhatsappShare = (ImageButton) dialoglayout.findViewById(R.id.ib_whatsapp_share);
mEmailShare = (ImageButton) dialoglayout.findViewById(R.id.ib_email_share);
mFlickrShare = (ImageButton) dialoglayout.findViewById(R.id.ib_flickr_share);
mTumblrShare = (ImageButton) dialoglayout.findViewById(R.id.ib_tumblr_share);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(dialoglayout);
dlg = builder.show();
mWhatsappShare.setOnClickListener(this);
mEmailShare.setOnClickListener(this);
mFlickrShare.setOnClickListener(this);
mTumblrShare.setOnClickListener(this);
}
});
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.ib_whatsapp_share:
sendIntent("com.whatsapp");
break;
case R.id.ib_email_share:
sendIntent("android.email");
break;
case R.id.ib_flickr_share:
sendIntent("com.yahoo.mobile.client.android.flickr");
break;
case R.id.ib_tumblr_share:
sendIntent("com.tumblr");
break;
}
}
``
On this block of code:
mWhatsappShare.setOnClickListener(this);
mEmailShare.setOnClickListener(this);
mFlickrShare.setOnClickListener(this);
mTumblrShare.setOnClickListener(this);
this is referring to the new OnClickListener you are creating - mOtherShare.setOnClickListener(new View.OnClickListener() and NOT your fragment's OnClickListener
To use the outer onClick, change this to YourFragment.this

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");
}
}

Variable OnClick Listener Android

Is there a way to have 1 onClick Lister for many buttons where I can toss a case statement to do things based on what buttons were clicked.
I know I can make 100 different listeners for 100 buttons but I have to think I can create some nifty variables to do it in less lines of code.
Button btn1, btn2;
public void onCreate(Bundle b)
{
// here you do normal things like assigning a
// content view to the activity, initiate buttons, etc.
// then you assign the same listener to both buttons
btn1.setOnClickListener(yourListener);
btn2.setOnClickListener(yourListener);
}
// declare a OnClickListener that will execute different actions
// depending on the view that was clicked
View.OnClickListener yourListener = new View.OnClickListener(){
public void onClick (View v){
if( v == btn1 ){
// do something
}
elseif( v == btn1 ){
// do another thing
}
}
};
If you are using 1.6+ version of the SDK you can use android:onClick to set the onClick handler of a view. In your activity you must have a method with the following signature. The view is the view that was clicked.
void onClick(View v) {
switch(v.getId()) {
case R.id.button1:
//do something fantastic;
break;
}
}
public class MainActivity extends Activity implements View.OnClickListener{
btnXXX.setOnClickListener(this);
public void onClick(View v) {
if (v.getId()==R.id.btnXXX){
dialog.show();
} else {
handleOtherViews(v);
}
}
Alternatively, you can specify the method to call in xml:
<Button android:id="#id/button" android:text="#string/button" android:onClick="someMethod" />

Categories

Resources