i have a method which displays a map. i call this method in onDraw method. but on Action move i need to redraw the map and need to call that method again but i am not getting canvas reference to redraw the map tiles. i used invalidate method but it start refreshing the onDraw frequently which made my map movement too to slow..
here is my onDraw method.
protected void onDraw(Canvas canvas)
{
Log.i("On Draw Call", "On Draw call");
mapMaker.getMapForScreenArea(map.getiScrnArea(), mapType, input, canvas);
invalidate();
this.canvas = canvas;
}
any help will be appreciative.
thanks a lot.
onDraw() gets called again and again because you invalidate() every time.
And also this.canvas = canvas is unnecessary.
Related
Following is my onDraw method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(inte < listOfPoints.size()){
canvas.drawLine(listOfPoints.get(0).x, listOfPoints.get(0).y, listOfPoints.get(inte).x,listOfPoints.get(inte).y, paint);
inte++;
if(inte < listOfPoints.size()){
invalidate();
}
}
}
Is it possible to get a callback once if the canvas has finished drawing the above point?
OnDraw is automatically called for situations that need to be drawn inside the view, so a Canvas is provided, so it will be called as long as the list size.
I extended the ViewPager with my class and overriden onDraw void like this:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
}
the problem is that whatever I draw in there, it scrolls with the ViewPager, but I want it to stay on the same place. I already tried setting canvas.translate(0,0); but that didn't work.
I would really appreciate any solution how to make the draw position static.
the easy solution is to translate() your Canvas before drawing your stuff:
canvas.translate(getScrollX(), 0);
// your drawing code follows...
In my OnDraw method, I draw path into my canvas (circle with segements). All work well, now what I am not sure how to do is how can I tilt it (sort of rotation around one axis).
Basically, what I am trying to achieve is something like the tilt functionality of google map.
Here is the pseduo code:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// I do all the drawing here
canvas.tilt(45degrees) <-----??
}
I don't think you have to create the tilt effect within the onDraw method modifying your canvas manually. Instead use setRotationX() method on the whole View. You can also define it in xml as android:rotationX="45".
Use Canvas.concat(Matrix) with a rotation matrix, i.e.:
class MyView {
private final Matrix rotate = new Matrix();
public MyView()
{
rotate.setRotate(45.0f);
}
protected void onDraw(Canvas c)
{
super.onDraw(canvas);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.concat(rotate);
canvas.restore();
}
}
Note also that you should not do any memory allocations inside onDraw() as per the android linter.
I've fooling around with 2D graphics in the Android SDK and I'm having trouble with what should be a simple example.
I'm assuming that I'm just misunderstanding something fundamental/basic.
public class DrawView extends View {
Paint paint = new Paint();
Canvas canvas = new Canvas();
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
this.canvas = canvas;
this.canvas.drawLine(0,0, 500, 500, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("DrawView", "onTouchEvent: " + event.getX() + "," + event.getY() );
canvas.drawLine(0,500, 500, 0, paint);
return true;
}
}
The code above draws a single line from 0,0 to 500,500 when the app start. That parts works just fine.
The issue is that the second line isn't drawn on the touch event. The onTouchEvent is definitely being called because I see the coordinates debug message in the log.
Can someone point out what silly thing I'm doing wrong?
You're supposed to call invalidate() at the end of onTouchEvent() to tell the system to update the screen. Calling invalidate() will call onDraw().
Also, what is fundamentally wrong is that you create a canvas in this class you have. That does absolutely nothing for you. The canvas to draw in is the one that you get from the onDraw() method. The call to canvas.drawLine() in onTouchevent isn't doing anything for you and shouldn't be there. That is an empty canvas and isn't the one that will get "posted."
In onTouchEvent() you should only gather the touch event data, and also do some processing on it if you need to. You shouldn't make any calls to drawing methods there. However, as I said, if you want to trigger a draw from onTouchEvent(), you call invalidate(). If you want to draw lines based on where you are touching, you will need to create class variables that are X and Y coordinates. You update these X and Y variables in onTouchEvent(), and then you use them in onDraw() to draw whatever you need based on these X and y variables.
Call postInvalidate() function. This function inform that view should be redrawed (event loop call onDraw() function).
You can declare a bool variable in your class, so that you can pass it to your ondraw() method that the user has touched and also pass X and Y with other float variables to ondraw() methode !
But you have to vall invalidate in onTouchEvet() so that the system will redraw the canvas using your new touch orders!
I am trying to write a small android app that redraws an image everytime the screen is touched.
I expected the image to be redrawn to the new x,y coordinates provided by event.getX() and event.getY() when I override the onTouch(Event) method in an activity.
Can anyone help?
I presume, you'd be having the Bitmap object for the image.
You could call the onDraw() method from the onTouch() method, to draw the bitmap. Here's a code sample which shows the overridden onDraw() method:
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(imgBitmap, x, y, null);
}
x,y are the new co-ordinates of the touch. imgBitmap is the Bitmap object for the image. You can update the instance variables x and y in the onTouch() method.
Hope this helps!!