Reputation: 342
I am creating a reusable class that implements an onclick and a method that sets the onclick. The class will represent "buttons" that are drawn on the canvas. I am aware of using the x and y positions to evaluate whether the button was pressed.
If you look at the code you can see an isPressed implemented which just returns this value (and this works only relevant for clarification).
What I need is to be able to give each item that is drawn on the canvas a distinct behaviour which is why I am trying to implement an onclick listener
public class CanvasButton extends CanvasItem implements View.OnClickListener {
private View.OnClickListener ClickListener;
public CanvasButton(float x, float y, int width, int height){
super(x, y, width, height);
}
public boolean isPressed(float x, float y){
return isTouched(x, y);
}
public void setOnClickListener(View.OnClickListener listener){
this.ClickListener = listener;
}
@Override
public void onClick(View v) {
}
}
Can't seem to figure how to proceed
UPDATE: I think I gave the wrong impression from the supplied code. I was trying the View.OnClickListener but that was just an option I thought I had. Any method that behaves like the onclick listener described above would do.
Upvotes: 4
Views: 188
Reputation: 950
You can only add onClickListeners and onClick methods to views. A canvas and anything inside it are not views and are not clickable. The only way to have a canvas with clickable buttons inside is to place the whole canvas in a view or a class that extends View, override the onTouch method, and in that method get the position of the touches and see if they are within the boundaries of any of your buttons so you can run some code. Here are links to some other StackOverflow questions.
and
add touch event listener to android canvas
public class MyCanvasView extends View implements OnTouchListener {
Bitmap button1;
Bitmap button2;
Bitmap button3;
Bitmap button4;
public MyCanvasView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
}
public void onDraw(Canvas canvas) {
paint = new Paint();
canvas.drawBitmap(button1, 10, 10, paint);
canvas.drawBitmap(button2, 60, 10, paint);
canvas.drawBitmap(button3, 110, 10, paint);
canvas.drawBitmap(button4, 160, 10, paint);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = event.getX();
int y = event.getY();
if (x >= 60 && x <= (60 + canvasButtonWidth)){
if (y >= 10 && x <= (10 + canvasButtonHeight)) {
//Insert code you want to use when button2 is clicked
}
}
/*Copy and paste the pair of if statements above for each button you have
/drawn on the canvas*/
return true;
}
}
Trying to get the Excavator badge!
Upvotes: 1
Reputation: 342
Thanks to @mdtuyen's answer I was able to rig something up that works for me. I implemented a base CanvasItem class that I can now inherit to do the trick (I left out the irrelevant class methods)
import android.view.View;
public class CanvasItem { //notice does not need to implement onClickListener
//this is used to get the click
private View.OnClickListener onClickListener;
protected CanvasItem(){
/* contructor logic goes here */
/* at minimum x and y and width and height is needed */
}
protected boolean isHit(float x, float y){
/* left() right() top() and bottom() use widths and height from my constructor */
/* x and y is passed from canvas ontouch */
if(x >= left() && x <= right() && y >= top() && y <= bottom()){
//fire any onclick listeners
if(onClickListener != null){
onClickListener.onClick(null);
}
//return true
return true;
}
//not touched
return false;
}
protected void setOnTouchListener(View.OnClickListener clickListener){
onClickListener = clickListener;
}
}
Once this is implemented I used an ArrayList of CanvasItem or class that inherits CanvasItem that is run to determine isHit()
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
float x = event.getX();
float y = event.getY();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
for(CanvasItem itm : mItems){
//if item istouched
if(itm.isHit(x, y)){
/* Logic can go here to alter any properties */
}
}
}
}
Nothing is needed to be in place in the if statement once the item.isHit() is fired then the onClick is fired.
Yes this implements something similar to what is normally done but using the onClick I can specifically action on touch without managing and keeping track of items on canvas which was an even greater task for items that were draggable on the canvas
Upvotes: 1
Reputation: 4548
OnClick need have format as:
@Override
public void onClick(View v) {
if (ClickListener != null){
ClickListener.onClick(v);
}
//The code to reuse
}
Upvotes: 3