【发布时间】:2013-11-08 16:37:22
【问题描述】:
更新:请再次阅读整个问题 :-)
背景:
我通过创建自定义视图然后将这些视图添加到TableLayout 来创建点网格。目的是让我能够以某种方式从这些点中的一个点到另一个点画一条线,以便当按下一个点时,一条线从按下的点的中心开始到手指当前所在的点接触。当手指被拖过另一个点时,线条会在该点的中心结束。结果是从按下的点的中心到手指拖过的点的中心绘制一条线。
为了在TableLayout 上创建一条线,我创建了一个新的自定义视图,它使用canvas.drawLine() 方法在点之间创建了一条线。然后我创建了一个FrameLayout,在其中放置了TableLayout 和LineView。这意味着线视图将能够绘制在 TableLayout 的顶部。
现状:
我在 DotView 类中添加了触摸监听器,以便它可以拥有自己的“触摸反馈”。活动中还有另一个触摸侦听器,我试图用它来获取绘制线所需的点。据我所知,触摸监听器工作正常 - 它们不会相互干扰。
问题是获取正确的坐标来绘制线条。我尝试了多种方法来获取按下的点的中心坐标(线的起点),但我仍然没有管理它。这个问题,有更多信息:Get the coordinates of the center of a view。第二部分是获取线的正确端点。出于这个问题的目的,我只想让行尾跟随手指的位置。我认为这和motionevent.getX() / getY() 一样简单,但这并没有奏效。相反,发生的事情是相对于点布局的比例坐标和相对于整个布局/屏幕的坐标之间存在混淆。
简单地说:getX() 和 getY() 值不正确,这就是我要解决的问题。
如截图所示,当我按下一个点时,线的起点大致在正确的位置,但终点却很远。我真的无法解释为什么。
我尝试了getRawX() 和getRawY(),它们返回的值更加准确,但填充量仍然不正确(或类似的东西 - 我不是 100% 理解)。
这显示了我的代码
在我的Activity:
LineView test;
FrameLayout fl;
float startPointX = 0;
float startPointY = 0;
// Removed
@Override
public boolean onTouch(View view, MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
int[] loc = new int[2];
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (view instanceof DotView) {
DotView touchedDv = (DotView) view;
int dotColor = touchedDv.getColor();
test.setColor(dotColor);
float[] f = touchedDv.getDotCenterLocationOnScreen();
startPointX = f[0];
startPointY = f[1];
test.setPoints(startPointX, startPointY, eventX, eventY);
fl.addView(test);
}
vib.vibrate(35);
return false;
case MotionEvent.ACTION_MOVE:
test.setPoints(startPointX, startPointY, eventX, eventY);
break;
case MotionEvent.ACTION_UP:
fl.removeView(test);
return false;
default:
return false;
}
return true;
}
最后是LineView:
public class LineView extends View {
public static final int LINE_WIDTH = 10;
Paint paint = new Paint();
float startingX, startingY, endingX, endingY;
public LineView(Context context) {
super(context);
paint.setColor(Color.MAGENTA);
paint.setStrokeWidth(LINE_WIDTH);
}
public void setPoints(float startX, float startY, float endX, float endY) {
startingX = startX;
startingY = startY;
endingX = endX;
endingY = endY;
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawLine(startingX, startingY, endingX, endingY, paint);
}
注意事项:
我正在调用左上角的点
"dot 1"。屏幕截图可能不完全准确,因为我的手指在移动 当我截屏时稍微有点,但我描述的行为是 正在发生。
如果需要任何其他信息/代码,我很乐意提供。
感谢您抽出宝贵时间阅读本文 - 抱歉,写了这么久!
【问题讨论】:
-
你解决了吗?如果不尝试更好地解释你在做什么。并且将触摸侦听器设置在层次结构中更高的视图而不是点视图上可能会更有意义,尤其是当您在其边界之外绘制时(从我在图像中看到的)。
-
@Luksprog 不,我还没有解决这个问题 - 我将编辑主要问题以尝试使其更清晰。我已将每个点视图注册到触摸侦听器,因此我可以首先检测在
ACTION_DOWN上按下了哪个点,然后检测手指已在ACTION_MOVE上拖过哪个点视图 -
@Luksprog 我主要更新了这个问题。我希望它现在更有意义。
标签: android android-canvas android-view touch-event motionevent