3

I'm writing a canvas app on android and I'm looking to add shadows, but I've noticed a great slow-down when I add them to my paint object. My code is simple it looks like this:

...
Paint paint = new Paint();
paint.setShadowLayer(8.f, 0, 0, 0xff000000); // this line makes terribly slow drawing
canvas.drawRect(left, top, right, bottom, paint);

How can I make this faster?

bryce
  • 698
  • 10
  • 11

3 Answers3

2

You can achieve almost the same result using this code instead:

mPaint.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.OUTER));

Muhammad Umair Shafique
  • 2,475
  • 1
  • 30
  • 39
2

While digging around to find a way to speed up my large text shadows, I stumbled on this question and answer:

setShadowLayer Android API differences

By using:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

I drastically sped up all the text shadows in my app.

Here is a sample of how I use it:

/**
 * Set a backlight (shadow) on the passed TextView.
 * @param textView
 */
void setBacklight(TextView textView) {
    if (textView != null) {
        float textSize = textView.getTextSize();

        textView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        textView.setShadowLayer(textSize,0,0,getColor(R.color.color_backlight));
    }
}

According to this doc:

https://developer.android.com/guide/topics/graphics/hardware-accel.html

It says that you can disable hardware acceleration for the view.

I don't know why, but somehow this magically speeds up my TextView shadow layers.

I know, I know. That method doesn't exist for the Canvas or Paint classes. So to answer the specific question (so I don't get blasted by everyone...), you could set that on the View that you intend to draw the canvas. Like this:

void inTheShadows(View view) {
    float left = 0f;
    float top = 0f;
    float right = 10f;
    float bottom = 10f;
    Canvas canvas = new Canvas();
    Paint paint = new Paint();

    paint.setShadowLayer(8.f, 0, 0, 0xff000000);

    canvas.drawRect(left, top, right, bottom, paint);

    view.setLayerType(View.LAYER_TYPE_SOFTWARE,null);

    view.onDrawForeground(canvas);
}
ByteSlinger
  • 1,439
  • 1
  • 17
  • 28
1

Use an image icon instead of drawing it :)

Yes shadowing is costly.

Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • 1
    What about drawing to a bitmap and caching it? Sometimes it's necessary to generate the path/shape at runtime... – User Jul 09 '17 at 13:21