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();
}
}
Related
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;
}
}
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
I have been looking at some posts and still I cannot get mine code to work (I am a beginner) .. I am just tring to use the toast with my two buttons with a case switch .. When compiling it just crashes .. one something has an idea ?
Code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
TextView et = (TextView) findViewById(R.id.txtHeader);
Button btnAdd = (Button) findViewById(R.id.btnAdd);
Button btnDis = (Button) findViewById(R.id.btnDisplay);
btnAdd.setOnClickListener((OnClickListener) this);
btnDis.setOnClickListener((OnClickListener) this);
}
public void OnClick(View v) {
switch (v.getId()) {
case R.id.btnAdd:
// Toast msg = Toast.makeText(getBaseContext(), "Torben", Toast.LENGTH_LONG);
// msg.show();
break;
case R.id.btnDisplay:
// Toast msg1 = Toast.makeText(getBaseContext(), "Henriksen", Toast.LENGTH_LONG);
// msg1.show();
break;
default:
break;
}
}
I see two main problems:
((OnClickListener) this
Make sure your class implements OnClickListener because you never need to cast if you are actually implementing the interface.'
The declaration of the class should be something like:
public class MyActivity extends Activity implements OnClickListener
Then change OnClick to lowercase o.
#Override
public void onClick(View v) {
some log output would be helpful!
a wild guess is that your activiy does not implement OnClickListener, why else would you cast this to OnClickListener?
just check in your layout manifest that whether the buttons id are correct and given the same id which your are using and if it is then please update the question with the LogCat output.
And also check that the activity is defined in manifest because there is no mistake in your code to implemts the onclick listener for multiple buttons.
Enjoy!!
Example adding a button listener:
Button b = ((Button)findViewById(R.id.button_name));
b.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
//do something
}
});
and make sure the button is defined in your xml file with the id #+id/button_name or #id/button_name (just make sure they match)
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
}
}
I'm having a button in a sliding drawer in a Android Application. The problem is it does not seem to react to any clicks as normal buttons do.
I'm guessing the problem is that it's a different view than buttons on the normal view.
If I implement a button the normal way like this
myAgenda = (Button)findViewById(R.id.BtnMyAgenda);
myAgenda.setOnClickListener(this);
public void onClick(View v) {
switch(v.getId()){
case R.id.BtnMyAgenda:
test.setAnimation(leftLeft);
test.startAnimation(leftLeft);
break;
}
I'm guessing there is something wrong with the above code since the button is in a SlidingDrawer and not in the "normal" view.
Any ideas how to fix the problem?
Here is the code
Register with event listner like below code
button.setOnClickListener(clickButtonListener);
and create this listner for button
private OnClickListener clickButtonListener= new OnClickListener()
{
#Override
public void onClick(View v)
{
if(v == button)
{
}
}
}
I actually found the solution to the problem, I simply created a new view.onclicklistener specific to that button.
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});