Reputation:
I added a flag(init) in my on draw that makes a 100x500 rect on View Creation but when i draw my testDraw method from the onTouch method nothing gets drawn.
DrawingView
class DrawingView extends View{
Canvas canvas= new Canvas();;
Paint paint= new Paint();
boolean init;
public DrawingView(Context context) {
super(context);
// TODO Auto-generated constructor stub
paint.setColor(Color.argb(255, 0, 255, 0));
this.init = true;
}
public void testDraw(){
canvas.drawRect(0,0,500,500,paint);
}
@Override
public void onDraw(Canvas canvas){
if(this.init == true){
canvas.drawRect(0,0,500,100,paint);
this.init = false;
}else{
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
testDraw();
}
return false;
}
}
Upvotes: 0
Views: 265
Reputation: 3621
Try this, this is a working example, if you draw anything on canvas, you should call an invalidate() method, to make a view to redraw, also a canvas in the testDraw method doesn't related to view, you should use a canvas from the onDraw parameter, or create a spearate bitmap for it
public class DrawingView extends View {
private Bitmap cachedBitmap;
private Canvas cachedCanvas;
private Paint linePaint;
private boolean isClicked;
private float lastX;
private float lastY;
public DrawingView(Context context) {
super(context);
}
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
if(cachedBitmap == null && width > 0 && height > 0) {
cachedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
cachedCanvas = new Canvas(cachedBitmap);
linePaint = new Paint();
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(3);
linePaint.setColor(Color.parseColor("#000000"));
}
canvas.drawBitmap(cachedBitmap, 0, 0, null);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isClicked = true;
break;
case MotionEvent.ACTION_MOVE:
if(isClicked && cachedCanvas != null) {
cachedCanvas.drawLine(lastX, lastY, event.getX(), event.getY(), linePaint);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
isClicked = false;
break;
}
lastX = event.getX();
lastY = event.getY();
return true;
}
}
Upvotes: 0
Reputation: 2909
Suggestion : you should keep the reference of your canvas in order to be able to work on it after onDraw has occured, like this :
class DrawingView extends View{
Canvas your_canvas= new Canvas(); /* change the variable name */
Paint paint= new Paint();
boolean init;
public DrawingView(Context context) {
super(context);
// TODO Auto-generated constructor stub
paint.setColor(Color.argb(255, 0, 255, 0));
this.init = true;
}
public void testDraw(){
your_canvas.drawRect(0,0,500,500,paint); /* changed variable name */
}
@Override
public void onDraw(Canvas canvas){
if(this.init == true){
your_canvas = canvas; /* keep canvas reference in your_canvas variable */
canvas.drawRect(0,0,500,100,paint);
this.init = false;
}else{
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
testDraw();
}
return false;
}
}
EDIT : according to @Budius you should not do this... so maybe calling the View.invalidate() method will allow you to reload onDraw, then do what you need (?)
Upvotes: 0
Reputation: 39856
that's because you're drawing to a different canvas then the one that is been shown on the screen.
The correct way of re-drawing a view is to invalidate it, like this:
private boolean testDrawn = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
testDrawn = true;
invalidate(); // << this will make on drawn be called again
}
return false;
}
then on the draw method
@Override
public void onDraw(Canvas canvas){
if(this.init == true){
canvas.drawRect(0,0,500,100,paint);
this.init = false;
}else if(testDrawn){
testDrawn = false;
// do the drawing here ...
}
}
and delete this line Canvas canvas= new Canvas();
the view should not have it's own canvas.
Upvotes: 1
Reputation: 1522
From the SDK Documentation:
onTouch() - This returns a boolean to indicate whether your listener consumes this event. The important thing is that this event can have multiple actions that follow each other. So, if you return false when the down action event is received, you indicate that you have not consumed the event and are also not interested in subsequent actions from this event. Thus, you will not be called for any other actions within the event, such as a finger gesture, or the eventual up action event. You need to return true when the ACTION_DOWN event is triggered to indicate that you are interested in the subsequent calls relating to that same event.
I think the problem is that you are returning false from onTouch and that means you are not interested in this event and subsequent action related to it. So I would suggest to return true from this.
Upvotes: 0