OnDraw method hides previous drawing - android

I am kinda new to android and I am creating a small app where I can draw rectangle and circle on custom view.
What I am trying to do is when Circle button is pressed I want to draw circle and when Rectangle button is pressed I want to draw a rectangle.
But the problem, I am having is when I press circle button it draws the circle correctly, but when I click on the rectangle button and tries to draw it, it hides the previous drawn circle and draws a rectangle. If again I select the circle, and draw it, it will hide the rectangle and draws a circle.
MainActivity.java: when button is pressed, buttonPressed method is called:
private DrawingView drawView;
public void buttonPressed(View v)
{
String shape = v.getTag().toString();
if(shape.equals("circle"))
{
Log.e("button pressed", "circle");
drawView.setValue("circle");
}
else if(shape.equals("rect"))
{
Log.e("button pressed", "rect");
drawView.setValue("rect");
}
}
and in my DrawingView class's onDraw method I am doing:
#Override
protected void onDraw(Canvas canvas)
{
if(testValue.equals("rect"))
{
// draw rectangle
}
else if(testValue.equals("circle"))
{
// draw circle
}
}
// setter method to set value
public void setValue(String val)
{
testValue = val;
}
Any suggestions on how to handle this situation?

Android Views will automatically clear their canvas before onDraw() is called, so you'll have to do one of two things:
Keep a list of items to draw, add to the list when a button is pressed, and iterate over it in onDraw(). This is simple to implement, but might slow down the draw process if your list gets long. This happens on the UI thread, so be careful.
Make your own Canvas from a private Bitmap matching the size of your View, and draw on it when a button is pressed. In onDraw(), use drawBitmap() to copy your buffer onto the View.

Related

Android moving a shape faster on Canvas

I have a class which is extended from ImageView (lets call it 'surface'). On onDraw method, a little dot is drawing on canvas. When I click a button I try to move this dot to another location. You can consider like manual version of translate animation. It works but now I try to figured out speed of this moving. I mean I want dot moving faster.
Relevant part of surface :
private float actual_x=100,actual_y=100; // Dot is drawn on 100,100 at beginning
private float increase_x,increase_y;
private boolean isMovingResume=false;
private int moving_counter;
public void changeLocation(float x,float y){
isMovingResume=true;
moving_counter=0;
increase_x=(x-actual_x)/50;
increase_y=(y-actual_y)/50;
invalidate(); // This trigger onDraw method
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(actual_x,actual_y,15,fill_paint);
if(isMovingResume){
actual_x=actual_x+increase_x;
actual_y=actual_y+increase_y;
if(moving_counter==49){ // Moving will end after 50 redraw
isMovingResume=false;
}
else{
moving_counter++;
}
invalidate(); //redraw
}
}
And my button click :
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
surface.changeLocation(200,200);
}
});
Like I said, it works but I want it more faster. For example, in this case moving time is 2 second, How can I make it 0,5 second ?
Thanks for all replies.
You need to switch to surfaceview or even faster textureview, both use a canvas as well, and have better performance. Textureview especially as it is hardware accelerated and I also feel it behaves better than surfaceview. That or even consider going to GLSurfaceView.
You can see some example code of surfaceview and textureview: Here

Android - Draw only parts which are visibile

I've created a custom view that draws via onDraw() overridden method some shapes. This view is scrollable so every time user navigates in the Activity, onDraw() method has called and all the canvas is drawn. In the onDraw() method there are some statements making some hard calculations so my intent is to draw, when user scrolls the view, only the part that were invisible and now, for the scrolling, they are visible.
How can I draw only the part that are visible in my custom view?
#Override
protected void onDraw(Canvas sysCanvas)
{
super.onDraw(sysCanvas);
if(!giaDisegnato) //If I've never drawn before, let's draw
{
if(!listaTl.isEmpty())
{
toDisk= Bitmap.createBitmap(w,h,Bitmap.Config.RGB );
canvas = new Canvas(toDisk);
canvas.drawColor(Color.WHITE);
p.setStyle(Paint.Style.FILL_AND_STROKE);
p.setAntiAlias(true);
p.setStrokeWidth(1);
for(TimelineGrafica t : listaTl)
{
if(inseritaLaPrima)
y = ySalvata + this.yAngoloDestroGiu + DISTANZA_FRA_TIMELINE;
p.setColor(t.getColor());
disegnaPunta(canvas,p,t);
disegnaRettangolo(canvas,p,t);
disegnaGrain(canvas,p,t);
disegnaFatti(canvas,p,t);
inseritaLaPrima = true;
}
y = ySalvata;
inseritaLaPrima = false;
sysCanvas.drawBitmap(toDisk,0,0,p);
}
requestLayout();
giaDisegnato = true;
}
else
{
//Here I've already drawn. So I'd like to redrawn the part of the view that now
//is visible.
sysCanvas.drawBitmap(toDisk,0,0,p);
}
}
Due to the language, it is difficult to know precisely what you are doing.
However, you can check the canvas to know whether you should draw or not using quickReject.
Example:
if(canvas.quickReject(boundingRect, EdgeType.BW)) {
return;
}

How do I draw a rectangle to a canvas on a button press (Android?)

My project actually has quite a few lines of code right now, so I'll save you by only including here what matters. I hope it's enough information to make the issue clear.
I have two main classes: a 'GraphView' class, and then the main Activity's code. Within GraphView, I've created a function which, essentially, draws a rectangle on a canvas. It's called drawPixel. In GraphView's onDraw method, I call drawPixel a bunch of times, and it draws rectangles to the screen. Now, in the main code, I've programmatically created a layout and a button. What I want is that instead of calling drawPixel in GraphView's onDraw method, I want to draw those rectangles when I click a button. I tried this by doing:
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Canvas canvas = new Canvas();
// TODO Auto-generated method stub
for (int i=1; i<50; i++) {
someGraphView.drawPixel(canvas, i, i);
}
}
});
It didn't work. The rectangles draw correctly when i call then via onDraw(), but they don't draw at all when I call them from inside a setOnClickListener method. Does anyone know what I'm doing wrong?
Once that's written call invalidate() on your View.

Canvas and drawing image in layout

I have a code where I draw image:
class Panel extends View {
public Panel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.calvin_logo_small);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(_scratch, x-point, y-point, null);
}
}
How can I draw this image in my activity, but I don't want to change may layout. I have layout: setContentView(R.layout.main); This is possible to draw in this lauout with canvas? I have this activity and this layout have a lot of components. I only want image in place where I click with canvas. This is idea. I start application where start activity with my setContentView(R.layout.main);. After that I click on the screen and canvas draw picture in place where I clicked. This is possible to do?
Your code should work. Just override the onTouchEvent() for the view, store the co-ordinates of the touch event in field variables and invalidate() the view so that onDraw() would be called. Use the co-ordinates in onDraw() to render the image as you've already done.
To improve performance, you can cache the bitmap if it's not going to change.

Android drawing button to canvas with custom view?

How can I draw a button on top of the canvas in a custom view? (Preferably on the mid-right side) Is there something I have to call before doing the button.draw(canvas)?
public class MyClass extends View {
public Simulation(Context context) {
super(context);
pauseButton.setText("TestButton");
pauseButton.setClickable(true);
pauseButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.i(TAG, "Button Pressed!");
}
});
public onDraw(Canvas canvas) {
super.onDraw(canvas);
pauseButton.draw(canvas);
}
}
Thanks for your time
You cannot insert a button into canvas. Canvas is an interface for bitmap or a bitmap buffer for a view. You can only draw other bitmap or pixels in it, not insert an object or a widget.
There are some solutions:
as Nikolay suggested, use a FrameLayout and create two layers (views), first your custom view and the second LinerView or RelativeView, which will come on top, where you can have buttons etc
draw an image of a buttun on Canvas then use onTouchEvent in your custom view and test for the coordinates of the touch, then do something... an example for onTouchEvent here: Make certain area of bitmap transparent on touch
Why do you need to draw the button yourself? Use a FrameLayout and simply have the button overlayed on your custom view.
Try this
public onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
pauseButton.draw(canvas);
canvas.restore();
}

Categories

Resources