Android How to create onClick events in Canvas onDraw method
Asked Answered
I

1

1

i've searched around and still can't find a good answer. I have made my own class that extends an imageView and in the onDraw() method i am using canvas to draw circles onto my image.

What i want to do now though is draw a button onto the image in different places and have an onClick event for it, so when the user presses the button it will open up a new activity..

Here is what I have so far..It draws the buttons in the right locations except my onClick method isn't firing

@Override
protected void onDraw(Canvas canvas){
    super.onDraw(canvas);

        //1.arrayList Points. 2.arrayLists for points in X, 3.arrayList for points in Y
        for(int i=0; i<arrayListPoints.size(); i++){


             Button b = new Button(mContext);
             LinearLayout ll = new LinearLayout(mContext);
             LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
             layoutParams.setMargins(alPoints_x.get(i), alPoints_y.get(i), 0, 0);

             ll.addView(b, layoutParams);

            //Measure and layout the linear layout before drawing it
             ll.measure(MeasureSpec.getSize(ll.getMeasuredWidth()), MeasureSpec.getSize(ll.getMeasuredHeight()));
             ll.layout(0, 0, MeasureSpec.getSize(b.getMeasuredWidth()), MeasureSpec.getSize(b.getMeasuredHeight()));
             //Finally draw the linear layout on the canvas
             ll.draw(canvas);


            //create an onClick event for the button
            b.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {

                     Toast msg = Toast.makeText(mContext, "button clicked \n", Toast.LENGTH_LONG);
                     msg.show(); 

                 } //end of public void

            });

        }


    invalidate();   

}   //end of onDraw()
Impellent answered 27/7, 2011 at 13:28 Comment(2)
You should not have to take setOnClickListener() in onDraw(). They should be in onCreate().Hannahannah
ive not seen onCreate() in a class that extends an imageView..i dont think you canImpellent
W
1

I have to say this approach may have a purpose but I don't see it. Why would you recreate and paint a layout each and every time your image view is redrawn?

The reason the onClick listener does not work is because you layout is never injected into the activities content, you are just painting it (which I would not have thought would have even worked so points for creativity) Also since the layout and button are not attached to anything I am pretty sure they would be garbage collected, which of course is irrelevant here, just saying.

Also this is happening every time you draw your canvas, which can't be good for performance or memory.

Is there some reason you are not just creating a layout with your imageview and button and then moving the button when you need to.

If you insist on this approach the only "solution" I can think of would be to keep track of the rect of the button in your image view and then check if a motion event "clicked" inside the area the button was drawn.

If you tell us why you are trying to do this, we can probably offer a better solution than this implementation, which really doesn't seem necessary or right but you might have a valid reason I can't think of.

Update

So I think based on your comments what you want to do is

Put an AbsoluteLayout container over your map (fill parent) or just place the map in such a container, either way.

Then put buttons into that layout container (via xml or programatically, doesn't really matter)

Then set the layout x/y/visibilty of those buttons

Wigwam answered 27/7, 2011 at 14:6 Comment(5)
In my activity class I am setting the contentView to a bitmap image using myCustomImageView (which has the onDraw()). The image is a map. The onDraw is called whenever a persons gps changes and draws their movement on the map (code taken out for this question). As well as that I have ArrayLists for geotagged media that I want to plot on the map. The ArrayLists contain the pixel x and pixel y coordinates. I can draw these coordinates easily. I do this by iterating through the ArrayList (as shown in the code) and calling drawCircle( code taken out for this question) - i replaced this with buttnImpellent
So in my onDraw - I now want to draw buttons on top of my map image in specific x/y coordinate locations and also have action listeners for these buttons. In my activity class I set my instance of this canvas class to the content view as well. Also this canvas is only drawn for my MapImageView which uses this customImageView (extends imageView)Impellent
@MrX ok see above modified answer, I think that would work for your and be easier as well.Wigwam
Thanks. I see what you mean. So in my activity class, instead of using a LinearLayout (which holds the image) , use an AbsoluteLayout instead and add my buttons dynamically in the activity instead of the onDraw method in the CustomImageViewImpellent
Yeah it has been, but you can still use it as far as I know, see all of this for reasoning, options etc. Personally I think google deciding that multiple screen sizes should prohibit absolute layouts is probably right but there are always special cases and I don't buy into the we know better than you philosophy. groups.google.com/group/android-developers/browse_thread/thread/… or developreality.blogspot.com/2009/05/… or #3539849Wigwam

© 2022 - 2024 — McMap. All rights reserved.