0

I'm trying to create a class that inherits Canvas class of Android. My reason is adding more robust and useful methods to that class for my game framework. When I tried to cast my AdvancedCanvas object to Canvas in onDraw() method. I do the drawing part in draw() method which takes an advancedcanvas object as a parameter. It causes an exception;

java.lang.ClassCastException: android.view.Surface$CompatibleCanvas cannot be cast to com.example.x.AdvancedCanvas

Here is my code block below

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        AdvancedCanvas advancedcanvas =  (AdvancedCanvas) canvas;
        draw(advancedcanvas);
    }

My real question is, is there any way to achieve that goal in the first place? Or any alternative ideas would be welcome. Thanks in advance.

Yekta Sarıoğlu
  • 1,435
  • 2
  • 12
  • 20

2 Answers2

0
  1. You cannot make cast like that. Since onDraw is and override method, it gets parameter from somewhere else above, which is a canvas.
  2. You can wrap that canvas object. make your AdvancedCanvas accept canvas as a parameter and hold ref to it inside, and add additional field and methods inside 'AdvancedCanvas'.

ex:

class AdvancedCanvas{
  private Canvas mCanvas;

  public AdvancedCanvas(Canvas canvas){ mCanvas = canvas }

  public void doSmt(){ //use mCanvas}
}

So you will be able to do:

onDraw(Canvas canvas){
 AdvancedCanvas ac = AdvancedCanvas(canvas);
}
Maksym V.
  • 2,877
  • 17
  • 27
0

In your codes, Canvas is a parent class, AdvancedCanvas is a child class. Upcasting from child to parent is always allowed, but downcasting from parent to child involves a type check and can throw a ClassCastException.

for example:

Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal?
if (animal instanceof Dog) { // only successful in this condition
    Dog castedDog = (Dog) animal;
}

But Canvas is not an instance of AdvancedCanvas , so error occured.

You could create a custom view if you like, this is a good example

Edited: Try this:

 @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        AdvancedCanvas advancedcanvas =  new AdvancedCanvas();

        advancedcanvas.property1 = canvas.property1;//prepare advancedcanvas 
        advancedcanvas.setProperty2(canvas.property2)//or like this

        draw(advancedcanvas);//then use advancedcanvas 
    }
navylover
  • 12,383
  • 5
  • 28
  • 41
  • Thanks for the explanation. But is there any way to achieve it with a different approach. Because I would like to get my clients to use AdvancedCanvas type as a parameter in draw() method. – Yekta Sarıoğlu Sep 18 '18 at 09:02
  • It is a good idea but unfortunately, there is no property that I can use in my class. Even Canvas class extends from BaseCanvas which have native methods from C++. I think this is an end of the story for my adventure :/ . But thanks anyway for trying. – Yekta Sarıoğlu Sep 18 '18 at 11:08