I'm trying to use onDraw method and canvas to draw some items in a bitmap and cache it to draw it again and don't call onDraw again
This is part of my code :
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCacheDrawing == null) {
mCacheDrawing = Bitmap.createBitmap(mScrollWidth, mScrollHeight, Config.RGB_565);
canvas.setBitmap(mCacheDrawing);
for (int i = 0; i < mIcons.size(); i++) {
prepareItem(canvas, paint, mIcons.get(i));
}
canvas.save();
} else {
canvas.setBitmap(mCacheDrawing);
}
}
The code is not working and show me an empty screen, can any one help me please?
EDIT : I have found the following post and it help me to solve the problem >> https://groups.google.com/forum/#!topic/android-beginners/6pO8SJN3CTY
and my working code now is following :
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCacheDrawing == null) {
mCacheDrawing = Bitmap.createBitmap(mScrollWidth, mScrollHeight, Config.RGB_565);
mCanvas = new Canvas(mCacheDrawing);
for (int i = 0; i < mIcons.size(); i++) {
prepareItem(mCanvas, paint, mIcons.get(i));
}
}
canvas.drawBitmap(mCacheDrawing,new Rect (0,0, mScrollWidth, mScrollHeight), new Rect (0,0, mScrollWidth, mScrollHeight), paint);
}
Well i can't figure out functionality of your code as its a snippet from a section, But what I can figures out is the reason. quick check
If you trying to draw bitmaps from a view, make sure drawing cache is enabled/
canvas.drawBitmap , this is the API for drawing a Bitmap over a canvas and not setBitmap
you can use save and restore method of canvas accordingly.
Related
Program reach in loadpng block....it also prints the toast "it shold draw something but it dont draw circle but draw all the remaining stuff that is in my arraylist"
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
int p=0,cir=0,r=0,l=0;
if(load_png)
{
Toast_Display.long_message(getContext(),"should draw something");
canvas.drawCircle(300,300,100,get_paint(Color.WHITE,10));
invalidate();
}
for(int sequence : sequence_draw)
{
if(sequence==1)
{
int color = color_name.get(p);
int width = brush_width.get(p);
Path mypath = path_list.get(p);
Paint paint = get_paint(color,width);
canvas.drawPath(mypath, paint);
p++;
}
else if(sequence==2)
{
circle c = circles.get(cir);
canvas.drawCircle(c.getCx(),c.getCy(),c.getRadious(),get_paint2(c.getColor(),c.getWidth()));
cir++;
}
else if(sequence==3)
{
Rectangle rec = rectangles.get(r);
canvas.drawRect(rec.getCx(),rec.getCy(),rec.getDx(),rec.getDy(),get_paint2(rec.getColor(),rec.getWidth()));
r++;
}
else if(sequence==4)
{
Rectangle line = lines.get(l);
canvas.drawLine(line.getCx(),line.getCy(),line.getDx(),line.getDy(),get_paint(line.getColor(),line.getWidth()));
l++;
}
}
if(draw==true)
{
if(status.equals("circle"))
canvas.drawCircle(cx,cy,radious,get_paint2(current_circle_color,current_circle_width));
else if(status.equals("rec"))
canvas.drawRect(cx,cy,dx,dy,get_paint2(current_Rectngle_color,current_Rectngle_width));
else if(status.equals("line"))
canvas.drawLine(cx,cy,dx,dy,get_paint(current_line_color,current_line_width));
}
}
I don't know why it's not drawing my required object in load png block.... any help will be appreciated
Try removing the invalidate() call. It does not make sense to call invalidate() inside onDraw(), since it is invalidation that causes oDraw() to be called in the first place!
The fact that you are calling it in onDraw() could be causing Android to do something unexpected.
My application is downloading a bitmap which is later populated into custom ImageView. However I want this bitmap to be updated before it is actually drawn on a canvas (I want to add some points over it). However as the result I see only populated bitmap without changes I made. Can anyone help?
Here is my onDraw method. "bitmap" object is set via setImageBitmap received from AsyncTask in onPostExecute() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap != null) {
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int padding = (width - bitmap.getWidth()) / 2;
canvas.drawBitmap(bitmap, padding, 0, null);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
for (Face face : getPhotoObject().getFaces()) {
canvas.drawPoint(face.getLeftEye().x, face.getLeftEye().y, paint);
canvas.drawPoint(face.getRightEye().x, face.getRightEye().y, paint);
}
}
}
You can create a canvas with a bitmap at any time:
Canvas canvas = new Canvas(myBitmap);
// draw code
// the resulting bitmap will be edited.
Hope this helps
I have the following code:
Bitmap right1;
public TicTacToe(Context context) {
super(context);
right1 = BitmapFactory.decodeResource(getResources(), R.drawable.plus);
int width = right1.getWidth();
int height = right1.getHeight();
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
right1 = Bitmap.createScaledBitmap(right1, canvas.getWidth()/3, canvas.getWidth()/3, false);
canvas.drawBitmap(right1, (canvas.getWidth() - (canvas.getWidth()/3)), 0, null);
invalidate();
}
I want to rescale the bitmap that is called "right1" based off of what the width of the canvas is. I succeeded in doing this, but the line of code that does this is the third line under the onDraw method. The problem with that line of code is that it will constantly loop when I would like to only run it once. Idealy I would like to put that line of code within the TicTacToe method, but I am unsure how to initialize the canvas within the TicTacToe method so that I can get the canvas width.
You don't need to do this stuff inside constructor just add condition in onDraw() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
if(right1==null){
right1 = Bitmap.createScaledBitmap(right1, canvas.getWidth() / 3, canvas.getWidth() / 3, false);
canvas.drawBitmap(right1, (canvas.getWidth() - (canvas.getWidth() / 3)), 0, null);
invalidate();
}
}
I'm currently developing android and went into a very serious problem :
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i("GAME", "onDraw Called");
for(int i = 0; i < totalEggNumbers -1; i++) {
if (egg[i].isKilled = false)
canvas.drawBitmap(image[egg[i].getEggNum()], egg[i].getX(), egg[i].getY() + 100, paint);
Log.i("GAME", "Something Drawn");
}
}
// called by thread
public void update() {
//Chance to make egg
Log.i("GAME", "Updated Game");
eggMaker.randomEgg(difficulty);
postInvalidate();
}
The onDraw never gets called and I cant find the log in logcat after I terminated the app, but when it is running, I could see one "onDraw Called" showing up and disappearing occasionally.
Im really desperate... I am using android view btw. Any way to call the onDraw method? I tried invalidate(); and no chance, please modify my code :)
Try to make your image as BitMap object before passing it to the drawBitMap methode
Bitmap bmp = BitmapFactory.decodeResource(
getResources(), image[egg[i].getEggNum());
I'm making an App that needs to be able to draw new graphics on top of the last set.
This is my current onDraw() method -
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
if(points.size() > 0) {
//do some stuff here - this is all working ok
canvas.drawLine(p1.x, p1.y, p2.x, p2.y, linePaint);
}
}
Basically, I need to draw the new graphics as a layer on top of the last, so what I'm looking for is a way to carry the image of the last canvas to the current.
I have tried to figure it out myself using the canvas.setBitmap() method but it acts very funny.
Any help appreciated :)
P.S if it's needed, the the class extends SurfaceView and implements SurfaceHolder.Callback
Edit: This is what I have tried in the onDraw() method but it just force closes
if(bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.setBitmap(bitmap);
}
Found the answer myself :)
#Override
protected void onDraw(Canvas c) {
if(bitmap != null && canvas != null) {
canvas.drawLine(p1.x, p1.y, p2.x, p2.y, linePaint);
c.drawBitmap(bitmap, 0, 0, linePaint);
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
}
Works exactly as intended, it creates the effect of drawing on top of the old canvas continuously
You will have to store the previous image persistently onto a ArrayList, and during ondraw, loop through the ArrayList to redraw all items.
something like this:
for (Graphic graphic : _graphics) {
bitmap = graphic.getBitmap();
coords = graphic.getCoordinates();
canvas.drawBitmap(bitmap, coords.getX(), coords.getY(), null);
}