Android: How to draw a rectangle on a movable imag

2019-07-11 21:31发布

问题:

I have an image which is movable throughout the screen. Now, I want to draw a rectangle on this image such that when I move the image the rectangle drawn on the image also moves. Currently I am able to draw the rectangle not on the image but on the SurfaceView which contains the image. My current code is below.

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);       


      int w=getWindowManager().getDefaultDisplay().getWidth()-25;
      int h=getWindowManager().getDefaultDisplay().getHeight()-25;

      MySurfaceView mySurface=new MySurfaceView(this,w,h);
      setContentView(mySurface);
  }
}

And I have a class called MySurfaceView.java

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

private Bitmap bitmap ;
private MyThread thread;
private int x=20,y=20;int width,height;

public MySurfaceView(Context context,int w,int h) {
    super(context);

    width=w;
    height=h;
    thread=new MyThread(getHolder(),this);
    getHolder().addCallback(this);
    setFocusable(true);
}

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

    bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.my_pic);
    canvas.drawColor(Color.BLUE);//To make background 
    canvas.drawBitmap(bitmap,x-(bitmap.getWidth()/2),y-(bitmap.getHeight()/2),null);


    Paint paintShape = new Paint();
    paintShape.setColor(Color.BLACK);
    paintShape.setStyle(Paint.Style.STROKE);

    Rect myRectangle = new Rect();
    myRectangle.set(0, 100, canvas.getWidth()/4, canvas.getHeight()/4);

    canvas.drawRect(myRectangle, paintShape);


}

@Override
public boolean onTouchEvent(MotionEvent event) {

    x=(int)event.getX();
    y=(int)event.getY();

    if(x<25)
            x=25;
     if(x> width)   
            x=width;
     if(y <25)
            y=25;
     if(y > 405)
            y=405;      
    return true;
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
    // TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {

    thread.startrun(true);
    thread.start();

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {


    thread.startrun(false);
    thread.stop();

}

public class MyThread extends Thread{

    private SurfaceHolder msurfaceHolder;
    private MySurfaceView mSurfaceView;
    private boolean mrun =false;

    public MyThread(SurfaceHolder holder, MySurfaceView mSurfaceView) {

        this.msurfaceHolder = holder;
        this.mSurfaceView=mSurfaceView;
    }

    public void startrun(boolean run) {

        mrun=run;
    }

    @SuppressLint("WrongCall")
    @Override
    public void run() {

        super.run();
         Canvas canvas;
         while (mrun) {
            canvas=null;
             try {
                 canvas = msurfaceHolder.lockCanvas(null);
                  synchronized (msurfaceHolder) {
                   mSurfaceView.onDraw(canvas);
                 }
             } finally {
                     if (canvas != null) {
                     msurfaceHolder.unlockCanvasAndPost(canvas);
                 }
             }
         }
      }
}

}

Can some one help me out improving my code to accommodate the above desired task. thanks!

回答1:

In onCreate, create a new Bitmap image and a canvas for that bitmap. Use that canvas to draw the original bitmap and a rectangle to the new bitmap. Then in onDraw just draw that new bitmap wherever you want to. As a bonus you'll have very fast onDraws.



回答2:

Well I figured my own way. It was just a small change in the above code which was necessary. It is enough to define the co-ordinates of rectangle with respect to x and y obtained due to touch events. for example, you can do the following:

myRectangle.set(x-50, y-50, x+50, y+50);

And the rest will be taken care automatically.