2012-06-02 84 views
9

我想在视图上的点之间绘制线条,然后将这些点拉到所需的位置,即使形状会改变。如何绘制点之间的线条并拉出这些点?

我知道如何绘制两点之间的线canvas.drawLine(10, 10, 90, 10, paint);通过使用这个我可以绘制点之间的线。

EDIT:我在这里附上图像清晰的解释,从保罗的回答现在我能画点之间的线路,还有拉点的问题...

enter image description here

+0

可以üPLZ发布整个代码?因为我非常需要这个代码....在此先感谢 –

+0

plz让我知道至少如何在onDraw()方法中实现这一点。 –

回答

7

以下是它的工作原理。假设你有你的积分,使这些全球性:

PointF topLeft = new PointF(10,10); 
PointF topRight = new PointF(90,10); 
PointF bottomLeft = new PointF(10,90); 
PointF bottomRight = new PointF(90,90); 

你需要做的是使每个点周围的RectF。 RectF越大,该点的触摸区域就越大。

float sizeOfRect = 5f; 
RectF topLeftTouchArea = new RectF(topLeft.x - sizeOfRect, topLeft.y - sizeOfRect, topLeft.x + sizeOfRect, topLeft.y + sizeOfRect); 
//Do this for the other points too 

定义一些全局变量来跟踪用户在onTouch中执行的操作。一个int是被触摸的角落,另外四个是角落的标识符。现在

private final int NONE = -1, TOUCH_TOP_LEFT = 0, TOUCH_TOP_RIGHT = 1, TOUCH_BOT_LEFT = 2, TOUCH_BOT_RIGHT = 3; 
int currentTouch = NONE; 

,在你onTouch事件,您可以检查哪些点你的用户触摸在这样的:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    switch (event.getAction()) { 
    //The user just put their finger down. 
    //We check to see which corner the user is touching 
    //And set our global, currentTouch, to the appropriate constant. 
    case MotionEvent.ACTION_DOWN: 
     if (topLeftTouchArea.contains(event.getX(), event.getY()) { 
      currentTouch = TOUCH_TOP_LEFT; 
     } else if (topRightTouchArea.contains(event.getX(),event.getY()) { 
      currentTouch = TOUCH_TOP_RIGHT; 
     } else if (botLeftTouchArea.contains(event.getX(),event.getY()) { 
      currentTouch = TOUCH_BOT_LEFT; 
     } else if (botRightTouchArea.contains(event.getX(), event.getY()) { 
      currentTouch = TOUCH_BOT_RIGHT; 
     } else { 
      return false; //Return false if user touches none of the corners 
     } 
     return true; //Return true if the user touches one of the corners 
    //Now we know which corner the user is touching. 
    //When the user moves their finger, we update the point to the user position and invalidate. 
    case MotionEvent.ACTION_MOVE: 
     switch (currentTouch) { 
     case TOUCH_TOP_LEFT: 
      topLeft.x = event.getX(); 
      topLeft.y = event.getY(); 
      //The bottom left x position has to move with the top left corner 
      bottomLeft.x = topLeft.x; 
      //The top right y position has to move with the top left corner 
      topRight.y = topLeft.y; 
      invalidate(); 
      return true; 
     case TOUCH_TOP_RIGHT: 
      topRight.x = event.getX(); 
      topRight.y = event.getY(); 
      //The top left y position has to move with the top right corner 
      topLeft.y = topRight.y; 
      //The bottom right x position has to move with the top right corner 
      bottomRight.x = topRight.x; 
      invalidate(); 
      return true; 
     case TOUCH_BOT_LEFT: 
      bottomLeft.x = event.getX(); 
      bottomLeft.y = event.getY(); 
      bottomRight.y = bottomLeft.y; 
      topLeft.x = bottomLeft.x; 
      invalidate(); 
      return true; 
     case TOUCH_BOT_RIGHT: 
      bottomRight.x = event.getX(); 
      bottomRight.y = event.getY(); 
      topRight.x = bottomRight.x; 
      bottomLeft.y = bottomRight.y; 
      invalidate(); 
      return true; 
     } 
     //We returned true for all of the above cases, because we used the event 
     return false; //If currentTouch is none of the above cases, return false 

    //Here the user lifts up their finger. 
    //We update the points one last time, and set currentTouch to NONE. 
    case MotionEvent.ACTION_UP: 
     switch (currentTouch) { 
     case TOUCH_TOP_LEFT: 
      topLeft.x = event.getX(); 
      topLeft.y = event.getY(); 
      //The bottom left x position has to move with the top left corner 
      bottomLeft.x = topLeft.x; 
      //The top right y position has to move with the top left corner 
      topRight.y = topLeft.y; 
      invalidate(); 
      currentTouch = NONE; 
      return true; 
     case TOUCH_TOP_RIGHT: 
      topRight.x = event.getX(); 
      topRight.y = event.getY(); 
      //The top left y position has to move with the top right corner 
      topLeft.y = topRight.y; 
      //The bottom right x position has to move with the top right corner 
      bottomRight.x = topRight.x; 
      invalidate(); 
      currentTouch = NONE; 
      return true; 
     case TOUCH_BOT_LEFT: 
      bottomLeft.x = event.getX(); 
      bottomLeft.y = event.getY(); 
      bottomRight.y = bottomLeft.y; 
      topLeft.x = bottomLeft.x; 
      invalidate(); 
      currentTouch = NONE; 
      return true; 
     case TOUCH_BOT_RIGHT: 
      bottomRight.x = event.getX(); 
      bottomRight.y = event.getY(); 
      topRight.x = bottomRight.x; 
      bottomLeft.y = bottomRight.y; 
      invalidate(); 
      currentTouch = NONE; 
      return true; 
     } 
     return false; 
    } 
} 

这样做是什么让你的周围点的矩形。想象一下,在图片中围绕你的要点画框。这些是由Rect对象创建的“触摸板”。矩形的大小由sizeOfRect设置。在onTouchEvent中,它检查每个矩形对象以查看用户的触摸是否在矩形内,表示用户试图触摸该点。

+0

我试过这个,但我仍然无法理解它正常。你可以分享任何教程这个.. –

+0

没有任何教程。编辑答案解释更多 –

+0

实际上,我正在使用一个主要活动,我称之为绘制方形的drwaSquare()函数,我无法将触摸侦听器称为该视图.. –

4

我想你可以寻找Path类:

Path类封装化合物(多轮廓)由直线段,二次曲线的几何 路径和 三次曲线。它可以用canvas.drawPath(路径,绘画), 绘制(基于绘制的样式),也可以使用 用于剪裁或在路径上绘制文本。

canvas.drawPath

+0

我怎样才能得到触摸听众的每一点.. –

+0

我不认为这些存在,但他们很容易创建。只需在点的正方形中间绘制小方块,然后点击测试以查看哪个点击并在点上执行拖动操作。其实,大声笑,这有点复杂,但不是很难得到正确的。 –

+0

我被编辑了我的问题与图像,我能够通过使用路径画线,触摸听众问题... –

2
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.graphics.PointF; 
import android.view.MotionEvent; 
import android.view.View; 

public class TestView extends View 
{ 

    private Paint paint; 
    private PointF startPoint, endPoint; 
    private boolean isDrawing; 

    public TestView(Context context) 
    { 
     super(context); 
     init(); 
    } 

    private void init() 
    { 
     paint = new Paint(); 
     paint.setColor(Color.RED); 
     paint.setStyle(Style.STROKE); 
     paint.setStrokeWidth(2); 
     paint.setAntiAlias(true); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) 
    { 
     if(isDrawing) 
     { 
      canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint); 
     } 
    } 


    @Override 
    public boolean onTouchEvent(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
       startPoint = new PointF(event.getX(), event.getY()); 
       endPoint = new PointF(); 
       isDrawing = true; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if(isDrawing) 
       { 
        endPoint.x = event.getX(); 
        endPoint.y = event.getY(); 
        invalidate(); 
       } 
       break; 
      case MotionEvent.ACTION_UP: 
       if(isDrawing) 
       { 
        endPoint.x = event.getX(); 
        endPoint.y = event.getY(); 
        isDrawing = false; 
        invalidate(); 
       } 
       break; 
      default: 
       break; 
     } 
     return true; 
    } 
} 
+0

courtsey http://stackoverflow.com/users/595543/shaiful –

+0

你的代码工作就像重画线你想拖动的点是什么,我不想重新绘制,只是用另一条线保留在前一点。 –

2

编辑的例子见this tutorial

你确实需要使用Path类机器人。对不起,我无法想出一个代码片段。但是,这是让你开始的东西。

当你画一条线 - canvas.drawLine(x1, y1, x2, y2, paint);你的出发点是(x1,y1)。现在,如果你需要从任何一端拉线,你需要先修复另一端。假设你从(x2,y2)拉。所以(x1,y1)变得不变,你从另一端拉。当使用Path类时,首先调用一个moveTo()到这个修复点。它所做的是给出一条关于该线路必须移动的点。然后,您可以使用触摸事件上的lineTo()调用来相应地拉伸线。很多调整将需要。但是,这可以让你开始。对不起,我不能拿出一小段,时间不多。请参阅Path类的文档。你可能会发现一些更有用的东西。


编辑:

关于添加触摸听众几点:

假设你有一个线从(x1,y1)(x2,y2)

现在为了获得一个点的监听器,你可以添加一个onTouchListener到你的整个视图。

final View touchView = findViewById(R.id.touchView); 
    touchView.setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
       if(event.getX() == x2 && event.getY() == y2) 
       { 
        //you know that you have clicked on the rear end of the line,so now you can do your dragging stuff. 
        if(event.getAction() == MotionEvent.ACTION_DOWN){ 
         //you know user has clicked in order to draw 
         //redraw the existing line with black color to remove it 
         paint.setColor(Color.BLACK); 
         canvas.drawLine(x1, y1, x2, y2, paint); 
         //reset the paint object 
         paint.setColor(Color.WHITE); 
         //now use moveTo() and lineTo() to attain the functionality of dragging on your Path object 
         path.moveTo(x1,y1); 
         path.lineTo(event.getX(),event.getY()); 
        }else if(event.getAction() == MotionEvent.ACTION_MOVE){ 
         path.lineTo(event.getX(),event.getY()); 
        }else if(event.getAction() == MotionEvent.ACTION_UP){ 
        } 
     } 
       return true; 
     } 
    }); 

这只是一个想法,我依然没有得到机会来测试它。我希望它有帮助。

+0

这只是用手指画,如果你没有让我知道,请阅读我的问题。 –

+0

ohh..ok ..你希望第一个用户点击一个点,然后点击另一个点,然后在这些点之间有一条线,对吧? –

+0

不,我已经有了两点之间的界线,现在我想拖动一点来延长线而不改变另一点..就像改变三角形的大小一样。 –

相关问题