2015-06-13 42 views
0

我是android studio的新手,我從stackoverflow中拿了一些代碼。我有一個問題,在2點之間畫一條線。我可以在2點之間畫一條線,例如:A到B到C.但是我想像他們那樣在他們之間畫線。像A到C或C到A.我也想在圖像背景上繪製這些線條。我有一個背景,但是當我畫背景線時,我的應用程序滯後。 下面的代碼:Android如何在2點之間繪製線條

package com.example.grzegorz.kropy; 
import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.Point; 
import android.graphics.drawable.*; 
import android.util.AttributeSet; 
import android.util.TypedValue; 
import android.view.MotionEvent; 
import android.view.View; 
import android.graphics.BitmapFactory; 
import java.util.ArrayList; 
import java.util.List; 
public class PaintView extends View { 

private Bitmap mBitmap; 
private Canvas mCanvas; // holds the "draw" calls 
private Path mPath; //Create an empty path 
private Paint mPaint; // the style and color information about how to draw geometries, text and bitmaps. 
private static final int TOUCH_TOLERANCE_DP = 24; 
private static final int BACKGROUND =0xFFCC00 ; 

private List<Point> mPoints = new ArrayList<Point>(); 
private int mLastPointIndex = 0; 
private int mTouchTolerance; 
private boolean isPathStarted = false; 


public PaintView(Context context) { 
    super(context); 

    mCanvas = new Canvas(); 
    mPath = new Path(); 
    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(Color.BLACK); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(12); 
    mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP); 

    // TODO just test points 
    Point p1 = new Point(20, 20); 
    Point p2 = new Point(100, 100); 
    Point p3 = new Point(200, 250); 
    Point p4 = new Point(280, 400); 
    Point p5 = new Point(350, 600); 
    Point p6 = new Point(400, 500); 
    Point p7 = new Point(450, 500); 
    mPoints.add(p1); 
    mPoints.add(p2); 
    mPoints.add(p3); 
    mPoints.add(p4); 
    mPoints.add(p5); 
    mPoints.add(p6); 
    mPoints.add(p7); 
} 

public PaintView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.polacz); 
    mCanvas = new Canvas(); 
    mPath = new Path(); 
    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(Color.BLACK); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(12); 
    mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP); 

    // TODO just test points 
    Point p1 = new Point(20, 20); 
    Point p2 = new Point(100, 100); 
    Point p3 = new Point(200, 250); 
    Point p4 = new Point(280, 400); 
    Point p5 = new Point(350, 600); 
    Point p6 = new Point(400, 500); 
    Point p7 = new Point(450, 500); 
    mPoints.add(p1); 
    mPoints.add(p2); 
    mPoints.add(p3); 
    mPoints.add(p4); 
    mPoints.add(p5); 
    mPoints.add(p6); 
    mPoints.add(p7); 
} 

public PaintView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    // TODO Auto-generated constructor stub 

    mCanvas = new Canvas(); 
    mPath = new Path(); 
    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(Color.BLACK); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(12); 
    mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP); 

} 

@Override 
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { 
    super.onSizeChanged(width, height, oldWidth, oldHeight); 
    clear(); 
} 
@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    //canvas.drawColor(BACKGROUND); 

    Drawable d = getResources().getDrawable(R.drawable.polacz); 
    d.setBounds(canvas.getClipBounds()); 
    d.draw(canvas); 
// mCustomImage.setBounds(canvas.getClipBounds()); 
// mCustomImage.draw(canvas); 
    canvas.drawBitmap(mBitmap, 0, 0, null); 
    // canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.polacz1), 0, 0, null); 
    canvas.drawPath(mPath, mPaint); 

    // TODO remove if you dont want points to be drawn 
    for (Point point : mPoints) { 
     canvas.drawPoint(point.x, point.y, mPaint); 
    } 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 

    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      touch_start(x, y); 
      invalidate(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      touch_move(x, y); 
      invalidate(); 
      break; 
     case MotionEvent.ACTION_UP: 
      touch_up(x, y); 
      invalidate(); 
      break; 
    } 
    return true; 
} 

private void touch_start(float x, float y) { 

    if (checkPoint(x, y, mLastPointIndex)) { 
     mPath.reset(); 
     // user starts from given point so path can beis started 
     isPathStarted = true; 
    } else { 
     // user starts move from point which doen's belongs to mPinst list 
     isPathStarted = false; 
    } 

} 
private void touch_move(float x, float y) { 
// draw line with finger move 
    if (isPathStarted) { 
     mPath.reset(); 
     Point p = mPoints.get(mLastPointIndex); 
     mPath.moveTo(p.x, p.y); 
     if (checkPoint(x, y, mLastPointIndex + 1)) { 
      p = mPoints.get(mLastPointIndex + 1); 
      mPath.lineTo(p.x, p.y); 
      mCanvas.drawPath(mPath, mPaint); 
      mPath.reset(); 
      ++mLastPointIndex; 
     } else { 
      mPath.lineTo(x, y); 
     } 
    } 
} 

/** 
* Draws line. 
*/ 
private void touch_up(float x, float y) { 
    mPath.reset(); 
    if (checkPoint(x, y, mLastPointIndex + 1) && isPathStarted) { 
     // move finished at valid point so draw whole line 

     // start point 
     Point p = mPoints.get(mLastPointIndex); 
     mPath.moveTo(p.x, p.y); 
     // end point 
     p = mPoints.get(mLastPointIndex + 1); 
     mPath.lineTo(p.x, p.y); 
     mCanvas.drawPath(mPath, mPaint); 
     mPath.reset(); 
     // increment point index 
     ++mLastPointIndex; 
     isPathStarted = false; 
    } 

} 

/** 
* Sets paint 
* 
* @param paint 
*/ 
public void setPaint(Paint paint) { 
    this.mPaint = paint; 
} 

/** 
* Returns image as bitmap 
* 
* @return 
*/ 
public Bitmap getBitmap() { 
    return mBitmap; 
} 

/** 
* Clears canvas 
*/ 
public void clear() { 
    mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
    mBitmap.eraseColor(BACKGROUND); 
    mCanvas.setBitmap(mBitmap); 
    invalidate(); 
} 

/** 
* Checks if user touch point with some tolerance 
*/ 
private boolean checkPoint(float x, float y, int pointIndex) { 
    if (pointIndex == mPoints.size()) { 
     // out of bounds 
     return false; 
    } 
    Point point = mPoints.get(pointIndex); 
    //EDIT changed point.y to poin.x in the first if statement 
    if (x > (point.x - mTouchTolerance) && x < (point.x + mTouchTolerance)) { 
     if (y > (point.y - mTouchTolerance) && y < (point.y + mTouchTolerance)) { 
      return true; 
     } 
    } 
    return false; 
} 

public List<Point> getPoints() { 
    return mPoints; 
} 

public void setPoints(List<Point> points) { 
    this.mPoints = points; 
} 

private int dp2px(int dp) { 
    Resources r = getContext().getResources(); 
    float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()); 
    return (int) px; 
} 
} 

XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context=".MainActivity" 
android:focusableInTouchMode="false"> 
<com.example.grzegorz.kropy.PaintView 
android:layout_width="670dp" 
android:layout_height="820dp" 
/> 

<!--<Button--> 
    <!--android:layout_width="wrap_content"--> 
    <!--android:layout_height="wrap_content"--> 
    <!--android:text="graj"--> 
    <!--android:id="@+id/button"--> 
    <!--android:layout_alignParentTop="true"--> 
    <!--android:layout_alignParentLeft="true"--> 
    <!--android:onClick="gra"--> 
    <!--android:layout_alignParentStart="true" />--> 
    </RelativeLayout> 
+0

那麼,這是否意味着你不能畫C到A和A到C的線條,或者只是它看起來太慢?你能提供關於用例的更多信息嗎?從代碼看起來,在開始繪製點時,只有在用戶用手指(觸摸輸入)繪製線條時才繪製線條?它是否正確? – Risadinha

+0

7點是在那裏開始繪製。我可以用手指在他們之間畫一條線。線條只能依次繪製。 p1到p2,p2到p3,p3到p4 ...我想自由地繪製它。關於繪圖的速度,當我添加圖像作爲背景時,我的應用程序正在落後。如果沒有這個背景,它就能順利運作 – Tranzts

回答

0
public class DrawingPanel extends View implements OnTouchListener { 

private Canvas mCanvas; 
private Path mPath; 
private Paint mPaint, mBitmapPaint; 
private ArrayList<PathPoints> paths = new ArrayList<PathPoints>(); 
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>(); 
private Bitmap mBitmap; 
private int color; 
public int SSL = Color.WHITE; 
private int x, y; 
private int strockWidth = 3; 

private String textToDraw = null; 
public static boolean isTextModeOn = false; 


//public static boolean flag = true; 
//public static int angle = 0; 

public DrawingPanel(Context context, int color, Bitmap bitmap) { 
    super(context); 
    this.color = color; 
    System.out.println("---> Drawing pannel Construction <--- "); 
    setFocusable(true); 
    setFocusableInTouchMode(true); 

    this.setOnTouchListener(this); 

    mBitmap = bitmap; 
    mBitmapPaint = new Paint(Paint.DITHER_FLAG); 
    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(color); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(strockWidth); 
    mPaint.setTextSize(30); 

    mPath = new Path(); 
    paths.add(new PathPoints(mPath, color,strockWidth, false)); 
    mCanvas = new Canvas(); 
} 

public void colorChanged(int color) { 
    this.color = color; 
    mPaint.setColor(color); 
    //invalidate(); 
} 

public void changeWidthOfStrock(int strockWidth) { 
    this.strockWidth = strockWidth; 
    mPaint.setStrokeWidth(strockWidth); 
    //invalidate(); 

} 



@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    // mBitmap = AddReportItemActivity.mPhoto; 
    //mBitmap = getIntent().getExtras().getParcelable("Bitmap"); 
    System.out.println("mBitmap"+mBitmap); 
    if(mBitmap != null) { 
     float xscale = (float) w/(float) mBitmap.getWidth(); 
     float yscale = (float) h/(float) mBitmap.getHeight(); 
     if (xscale > yscale) // make sure both dimensions fit (use the 
      xscale = yscale; 
     float newx = (float) w * xscale; 
     float newy = (float) h * xscale; // use the same scale for both 
             // dimensions 
    } 
    // if you want it centered on the display (black borders) 
    mBitmap = Bitmap.createScaledBitmap(mBitmap, this.getWidth(),this.getHeight(), true); 
    // mCanvas = new Canvas(mBitmap); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    for (PathPoints p : paths) { 
     mPaint.setColor(p.getColor()); 
     mPaint.setStrokeWidth(p.getStrockWidth()); 
     if (p.isTextToDraw()) { 
      //canvas.drawText(p.textToDraw, p.x, p.y, mPaint); 
     } else { 
      canvas.drawPath(p.getPath(), mPaint); 
     } 
    } 
    mPaint.setColor(SSL); 
    mPaint.setStrokeWidth(strockWidth); 
    canvas.drawPath(mPath, mPaint); 
} 

private float mX, mY; 
private static final float TOUCH_TOLERANCE = 0; 

private void touch_start(float x, float y) { 
    mPath.reset(); 
    mPath.moveTo(x, y); 
    mX = x; 
    mY = y; 
} 

private void touch_move(float x, float y) { 
    float dx = Math.abs(x - mX); 
    float dy = Math.abs(y - mY); 
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
     mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
     mX = x; 
     mY = y; 
    } 
} 

private void touch_up() { 
    mPath.lineTo(mX, mY); 
    // commit the path to our offscreen 
    mCanvas.drawPath(mPath, mPaint); 
    // kill this so we don't double draw 
    //mPath = new Path(); 
    paths.add(new PathPoints(mPath, SSL,strockWidth ,false)); 
    mPath = new Path(); 

} 

private void drawText(int x, int y) { 
    //Log.v(TAG, "Here"); 
    //Log.v(TAG, "X " + x + " Y " + y); 
    this.x = x; 
    this.y = y; 
    paths.add(new PathPoints(color, textToDraw, true, x, y)); 
    // mCanvas.drawText(textToDraw, x, y, mPaint); 
} 

@Override 
public boolean onTouch(View arg0, MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 

    switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     if (!isTextModeOn) { 
      touch_start(x, y); 
      invalidate(); 
     } 
     break; 
    case MotionEvent.ACTION_MOVE: 
     if (!isTextModeOn) { 
      touch_move(x, y); 
      invalidate(); 
     } 
     break; 
    case MotionEvent.ACTION_UP: 
     if (isTextModeOn) { 
      drawText((int) x, (int) y); 
      invalidate(); 
     } else { 
      touch_up(); 
      invalidate(); 
     } 
     break; 
    } 
    return true; 
} 

public void onClickUndo() { 
    if (paths.size() > 0) { 
     undonePaths.add(paths.remove(paths.size() - 1)); 
     invalidate(); 
    } else { 

    } 
    // toast the user 
} 

public void onClickRedo() { 
    if (undonePaths.size() > 0) { 
     paths.add(undonePaths.remove(undonePaths.size() - 1)); 
     invalidate(); 
    } else { 

    } 
    // toast the user 
} 


class PathPoints { 
    private Path path; 
    // private Paint mPaint; 
    private int color; 
    private int strockW; 
    private String textToDraw; 
    private boolean isTextToDraw; 
    private int x, y; 

    public PathPoints(Path path, int color,int strockWidth ,boolean isTextToDraw) { 
     this.path = path; 
     this.color = color; 
     this.strockW = strockWidth; 
     this.isTextToDraw = isTextToDraw; 
    } 

    public PathPoints(int color, String textToDraw, boolean isTextToDraw,int x, int y) { 
     this.color = color; 
     this.textToDraw = textToDraw; 
     this.isTextToDraw = isTextToDraw; 
     this.x = x; 
     this.y = y; 
    } 

    public Path getPath() { 
     return path; 
    } 

    public void setPath(Path path) { 
     this.path = path; 
    } 

    /* 
    * private Paint getPaint() { mPaint = new Paint(); 
    * mPaint.setAntiAlias(true); mPaint.setColor(color); 
    * mPaint.setStyle(Paint.Style.STROKE); 
    * mPaint.setStrokeJoin(Paint.Join.ROUND); 
    * mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(6); 
    * return mPaint; } 
    */ 

    public int getColor() { 
     return color; 
    } 

    public void setColor(int color) { 
     this.color = color; 
    } 

    public int getStrockWidth() { 
     return strockW; 
    } 

    public void setStrokWidth(int color) { 
     this.strockW = color; 
    } 

    public String getTextToDraw() { 
     return textToDraw; 
    } 

    public void setTextToDraw(String textToDraw) { 
     this.textToDraw = textToDraw; 
    } 

    public boolean isTextToDraw() { 
     return isTextToDraw; 
    } 

    public void setTextToDraw(boolean isTextToDraw) { 
     this.isTextToDraw = isTextToDraw; 
    } 

    public int getX() { 
     return x; 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    public int getY() { 
     return y; 
    } 

    public void setY(int y) { 
     this.y = y; 
    } 

} 

}


添加這種觀點到您的佈局

DrawingPanel drawingPanel =新DrawingPanel(getApplicat ionContext(),顏色,位圖); rl_layout.addView(drawingPanel);

+0

我應該在哪裏添加這個視圖到我的佈局?我用DrawingPanel添加新的Java類。 – Tranzts

+0

在主佈局

0
Try this Hope so it will be helpful for you 

public class DrawView extends View { 
     Paint paint = new Paint(); 
     View startView1; 
     View endView1; 
     int myToken; 
     float sX,sY,eX,eY; 
     public DrawView(Context context,View startView ,View endView) { 
      super(context); 
      paint.reset(); 
      myToken=token; 
      paint.setStrokeWidth(3); 
      this.startView1 = startView; 
      this.endView1 = endView; 

     } 

public void onDraw(Canvas canvas) { 

      paint.setColor(Color.GREEN); 
      canvas.drawLine(startView1.getX()+startView1.getWidth()/2.F, startView1.getY()+startView1.getHeight()/ 2.F, endView1.getX()+endView1.getWidth()/2.F, endView1.getY()+endView1.getHeight()/2.F, paint); 

     } 

    } 


and call this DrawView class as : 

Button btn1=(Button) findViewById(id1); 
            Button btn2=(Button) findViewById(id2); 
            DrawView drawView = new DrawView(RoasterScreen.this,btn1,btn2); 
+0

修改代碼後它工作謝謝。 –

相關問題