May 5, 2011

Drawing on SurfaceView

Last post introduce "A basic implementation of SurfaceView". To draw something on the SurfaceView, place the codes in-between surfaceHolder.lockCanvas() and surfaceHolder.unlockCanvasAndPost(canvas).

Drawing on SurfaceView

package com.TestSurefaceView;

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class TestSurefaceView extends Activity {
 
 MySurfaceView mySurfaceView;
 
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       mySurfaceView = new MySurfaceView(this);
       setContentView(mySurfaceView);
   }
  
   @Override
 protected void onResume() {
  // TODO Auto-generated method stub
  super.onResume();
  mySurfaceView.onResumeMySurfaceView();
 }

 @Override
 protected void onPause() {
  // TODO Auto-generated method stub
  super.onPause();
  mySurfaceView.onPauseMySurfaceView();
 }

 class MySurfaceView extends SurfaceView implements Runnable{
    
    Thread thread = null;
    SurfaceHolder surfaceHolder;
    volatile boolean running = false;
    
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Random random;

  public MySurfaceView(Context context) {
   super(context);
   // TODO Auto-generated constructor stub
   surfaceHolder = getHolder();
   random = new Random();
  }
  
  public void onResumeMySurfaceView(){
   running = true;
   thread = new Thread(this);
   thread.start();
  }
  
  public void onPauseMySurfaceView(){
   boolean retry = true;
   running = false;
   while(retry){
    try {
     thread.join();
     retry = false;
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }

  @Override
  public void run() {
   // TODO Auto-generated method stub
   while(running){
    if(surfaceHolder.getSurface().isValid()){
     Canvas canvas = surfaceHolder.lockCanvas();
     //... actual drawing on canvas

     paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(3);
     
     int w = canvas.getWidth();
     int h = canvas.getHeight();
     int x = random.nextInt(w-1); 
     int y = random.nextInt(h-1);
     int r = random.nextInt(255);
     int g = random.nextInt(255);
     int b = random.nextInt(255);
     paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
     canvas.drawPoint(x, y, paint);
     
     surfaceHolder.unlockCanvasAndPost(canvas);
    }
   }
  }
    
   }
}


Related Post:
- Handle onTouchEvent in SurfaceView
- Draw path on SurfaceView's canvas

11 comments:

  1. Thanks for the simple examples I like your posts.

    ReplyDelete
  2. hey please can you tell me how to record this SurfaceView so that i can play it later on when required.

    ReplyDelete
  3. hello,,
    could you please tell me how to change the SurfaceView
    parameters like this
    [surfaceView.setLayoutParams(new FrameLayout.LayoutParams(X,Y));]
    I want make like this to do zoom ,,
    Many thanks
    Anas

    ReplyDelete
  4. what about drawing on top of a surfaceview background image, like with drawRect.

    ReplyDelete
  5. A general question: All SurfaceView implementations I saw so far use a thread which continously draws in an infinite loop. However, in many apps the image only changes after some user event, so redrawing the same image over and over again seems a big waste of CPU power. How could we implement some Invalidate() / OnDraw() scheme, where drawing only takes places after a user event? (But still use a second thread to keep the load from the main GUI thread...)

    ReplyDelete
    Replies
    1. Hermann, just inherit your view from View and implement onDraw()

      Delete
  6. terrible graphic animation skills ! just joking. thanks, this helped me a lot

    ReplyDelete
  7. sourav bor phukon's comment is hilarious !

    ReplyDelete
  8. thanks for it, Can you help me ?, Actually i have a problem
    on canvas on surface view. The problem is that when i touch screen for drawing then drawing not shown but when release the finger from the screen then drawing has seen.
    my email-hemant.katariya26@gmail.com
    My small code is
    public boolean onTouch(View view, MotionEvent motionEvent) {
    if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){

    currentDrawingPath = new DrawingPath();
    currentDrawingPath.paint = currentPaint;
    currentDrawingPath.path = new Path();
    currentBrush.mouseDown(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY());

    }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){

    currentBrush.mouseMove( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );

    }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
    currentBrush.mouseUp( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );
    drawingSurface.addDrawingPath(currentDrawingPath);

    }

    return true;
    }

    ReplyDelete
    Replies
    1. hello,

      I don't know the details of your DrawingPath.

      Please read my simple example: Draw path on SurfaceView's canvas.

      Delete

Infolinks In Text Ads