一个Canvas如何设置点击事件?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个Canvas如何设置点击事件?相关的知识,希望对你有一定的参考价值。

MapView 里面的Overlay都是Canvas画的、可以用点击事件。不是说整个canvas,而是canvas里面画很多按钮,然后点击每个按钮都能有事件。。

参考技术A <div id=cd>
<canvas width="300" height="300" style="border:1px solid #c3c3c3;">
</canvas>
</div>
<scripr>
var pp=document.getElementById("cd");
pp.onclick=function(e)
e=e||event;
var x=e.clientX-pp.offsetLeft;//获取点击后x的坐标
var y=e.clientY-pp.offsetTop;//获取点击后y的坐标
alert(x);
alert(y);

</scripr>
参考技术B canvas已经不是其他view那种被系统托管各种事件了的,这个比较原始,事件什么的需要你自己判断。其实系统做的事情不也就是判断坐标,定位具体的view么。

Android 如何在 Canvas 的 onDraw 方法中创建 onClick 事件

【中文标题】Android 如何在 Canvas 的 onDraw 方法中创建 onClick 事件【英文标题】:Android How to create onClick events in Canvas onDraw method 【发布时间】:2011-07-27 13:28:22 【问题描述】:

我四处寻找,仍然找不到好的答案。我已经创建了自己的类来扩展 imageView,并且在 onDraw() 方法中我使用画布在我的图像上绘制圆圈。

我现在想做的是在不同位置的图像上绘制一个按钮并为其设置一个 onClick 事件,因此当用户按下按钮时它将打开一个新活动..

这是我到目前为止所拥有的......它在正确的位置绘制按钮,除了我的 onClick 方法没有触发

@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()

【问题讨论】:

你不应该在 onDraw() 中使用 setOnClickListener()。它们应该在 onCreate() 中。 在扩展 imageView 的类中没有看到 onCreate() ..我认为你不能 【参考方案1】:

我不得不说这种方法可能有目的,但我没有看到它。为什么每次重绘图像视图时都要重新创建和绘制布局?

onClick 侦听器不起作用的原因是因为您的布局从未注入到活动内容中,您只是在绘制它(我没想到它甚至会为创造力点数)另外因为布局和按钮不附加任何东西我很确定它们会被垃圾收集,这在这里当然是无关紧要的,只是说。

每次绘制画布时都会发生这种情况,这对性能或内存没有好处。

是否有某些原因,您不只是使用图像视图和按钮创建布局,然后在需要时移动按钮。

如果您坚持使用这种方法,我能想到的唯一“解决方案”是跟踪图像视图中按钮的矩形,然后检查是否在绘制按钮的区域内“单击”了运动事件.

如果你告诉我们你为什么要这样做,我们可能会提供比这个实现更好的解决方案,这看起来确实没有必要或正确,但你可能有一个我想不出的正当理由。

更新

所以我认为根据你的 cmets 你想要做的是

在您的地图上放置一个 AbsoluteLayout 容器(填充父级)或将地图放在这样的容器中,无论哪种方式。

然后将按钮放入该布局容器中(通过 xml 或以编程方式,并不重要)

然后设置这些按钮的布局 x/y/visibilty

【讨论】:

在我的活动类中,我使用 myCustomImageView(具有 onDraw())将 contentView 设置为位图图像。图像是地图。每当一个人的 gps 发生变化并在地图上绘制他们的移动时都会调用 onDraw(为此问题取出的代码)。除了我想在地图上绘制的地理标记媒体之外,我还有 ArrayLists。 ArrayLists 包含像素 x 和像素 y 坐标。我可以轻松绘制这些坐标。我通过遍历 ArrayList(如代码所示)并调用 drawCircle(为此问题取出的代码)来做到这一点 - 我用 buttn 替换了它 所以在我的 onDraw 中 - 我现在想在我的地图图像顶部的特定 x/y 坐标位置绘制按钮,并且还有这些按钮的动作监听器。在我的活动类中,我也将此画布类的实例设置为内容视图。此外,此画布仅为我的 MapImageView 绘制,它使用此 customImageView(扩展 imageView) @MrX 好的,请参阅上面修改后的答案,我认为这对您有用并且也更容易。 谢谢。我明白你的意思了。因此,在我的活动类中,不要使用 LinearLayout(保存图像),而是使用 AbsoluteLayout 并在活动中动态添加我的按钮,而不是在 CustomImageView 中使用 onDraw 方法 是的,但据我所知,您仍然可以使用它,请参阅所有这些以进行推理、选项等。我个人认为谷歌决定多种屏幕尺寸应该禁止绝对布局可能是是的,但总会有特殊情况,我不认同我们比你更了解的哲学。 groups.google.com/group/android-developers/browse_thread/thread/… 或 developreality.blogspot.com/2009/05/… 或 ***.com/questions/3539349/…

以上是关于一个Canvas如何设置点击事件?的主要内容,如果未能解决你的问题,请参考以下文章

H5如何在 canvas 插入的图片上添加点击方法

为啥小弟我的canvas的鼠标事件不会触发

android canvas view重绘 我在一个activity中调用了canvas。在canvas中我点击事件需要重新绘制当前view

android中如何设置处理点击按钮事件

canvas是怎么响应鼠标事件的

如何捕捉鼠标点击事件到重叠的ItemsControl