Home » Android » android – Canvas not displaying all drawn parts in Custom View?

android – Canvas not displaying all drawn parts in Custom View?

Posted by: admin June 15, 2020 Leave a comment


I’m working on a custom view for an android application, similar to the Analog Gauge sample code available from Mind the Robot.

Running the code from listed site, I get see this on my screen:

(Motorola Droid, 2.2.3), (Emulator, 4.0.3)

has an arrow

(Xoom, 4.0.3)(Other phone, 4.0.3)

does not have an arrow

The hand is missing!

The drawing calls are being made (I can see them in logcat), but the canvas elements the calls draw are invisible.

It’s not API level dependent, though; if I import it the right way into a project, it will hand will show up when I run it on the Xoom.

But, when I move the files to a different project folder (same source code, same layouts) it goes back to missing the dial.

What’s going on? How could the same code be producing such different outcomes on different devices?

How to&Answers:

So, the key clue in my mystery seemed to be that it worked on the emulator, but not on the hardware devices.

Hardware Rendering

I did peruse the hardware rendering page on the Android Developer’s website, but apparently not closely enough.


While it does mention that the API’s are available beginning version 11, it does not say that Hardware Rendering is turned on for all applications by default, starting with API Level 14 (ICS).

What does this mean for us?

Almost everything is faster; except for the few things that don’t work.

I managed to violate two of these, without realizing it:

  • Canvas.DrawTextOnPath()
  • Paint.setShadowLayer()

It’s not mentioned in the API reference (or anywhere else I can find, and certainly not checked by Lint), but using any of the listed operations can do weird things.

In my case, Canvas.DrawTextOnPath() seemed to work just fine.

But when Android notice that the paint that I used on the hand had shadow layer set, it silently ignored it.

How do I know if my View is hardware accelerated?

From the documentation link above:

There are two different ways to check whether the application is hardware accelerated:

  • View.isHardwareAccelerated() returns true if the View is attached to a hardware accelerated window.
  • Canvas.isHardwareAccelerated() returns true if the Canvas is hardware accelerated

If you must do this check in your drawing code, use Canvas.isHardwareAccelerated() instead >of View.isHardwareAccelerated() when possible. When a view is attached to a hardware >accelerated window, it can still be drawn using a non-hardware accelerated Canvas. This >happens, for instance, when drawing a view into a bitmap for caching purposes.

In my case, the opposite appears to have occurred.
The custom view logs that it is not Hardware-accelerated; however, the canvas reports that it is hardware-accelerated.

Work Arounds and Fixings

The simplest fix is forcing the custom view to do software rendering. Per the documentation this can be accomplished by:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Alternatively, you could remove the offending operations, and keep hardware rendering turned on.

Learn from my misfortune. Good luck, all.


I put it into init() and worked fine after that.

    private void init() {
    setLayerType(myView.LAYER_TYPE_SOFTWARE, null);


With myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); suggestion I can see hand. But I have still a problem: I see scale with only 0 written! As in the picture and two strage zeros out of the schema: (GALAXY NEXUS 4.2.1)

enter image description here

My drawScale() method is as in the example:

 private void drawScale(Canvas canvas) {
        canvas.drawOval(scaleRect, scalePaint);

        for (int i = 0; i < totalNicks; ++i) {
            float y1 = scaleRect.top;
            float y2 = y1 - 0.020f;

            canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);

            if ((i % 5) == 0) {
                int value = nickToDegree(i);

                if ((value >= minDegrees) && (value <= maxDegrees)) {
                    String valueString = Integer.toString(value);
                    canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);


            canvas.rotate(degreesPerNick, 0.5f, 0.5f);




in my case i made this:

 AnalogView bar = (AnalogView) findViewById(R.id.AnalogBar);
    bar.setLayerType(bar.LAYER_TYPE_SOFTWARE, null);
if (value_list.size()>0)   bar.SetData(Double.parseDouble(value_list.get(value_list.size()-1)));

where SetData in AnalogView is

public  void SetData(double data) {


On Galaxy S4 Android 4.4.2

TYPE_TEMPERATURE is deprecated




For anyone having problems with text drawing on scale in the initialisation do this: