39

I develop a custom view component for my application and I am struggling with adding a shadow to a circle.

Here is the code of my class extending View

public class ChartView extends View {


    public ChartView(Context context, AttributeSet attributeSet){
        super(context, attributeSet);
        init();


    }
    Paint paint;
    public void init(){
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setShadowLayer(30, 0, 0, Color.RED);

    }
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawCircle(getWidth()/2, getHeight()/2,50, paint);
    }
}

However, I noticed that depending on the API, There is a big impact on the shadowLayer.

Here is the output with

<uses-sdk android:targetSdkVersion="13"/>

enter image description here

And here is the output with

<uses-sdk android:targetSdkVersion="14"/> //Higher target API yields the same output.

enter image description here

Any idea how to overcome this unwanted behaviour?

Dharman
  • 30,962
  • 25
  • 85
  • 135
Al_th
  • 1,174
  • 1
  • 12
  • 24

1 Answers1

77

setShadowLayer() is only supported on text when hardware acceleration is on. Hardware acceleration is on by default when targetSdk=14 or higher. An easy workaround is to put your View in a software layer: myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null).

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • Thanks, this worked right away. I did not see this in the android documentation, this might help people in the future. – Al_th Jul 02 '13 at 06:58
  • 5
    It's documented right here: http://developer.android.com/guide/topics/graphics/hardware-accel.html :)) – Romain Guy Jul 03 '13 at 05:34
  • 3
    Thanks for the additional info. I was looking in the Canvas documentation, bad on me ! – Al_th Jul 03 '13 at 07:35
  • I use Path.offset(). I write down my problem here: http://stackoverflow.com/questions/27422681/path-offset-not-working-on-every-device . Now I realised, if I use myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null) it works okay on every device. Can I give some condition, where I don't turn it off. I mean it was working well on some device. maybe something like: just turn off hardware acc mode if (android.os.Build.VERSION.SDK_INT <= 14) – Tomi Dec 11 '14 at 20:04
  • Thanks, I found that hardware acceleration is off in Android 6.0. – BinqiangSun Feb 25 '16 at 03:14
  • 1
    Why is the shadow drawn with LAYER_TYPE_SOFTWARE much darker than when the view is hardware accelerated? (API 26) – User Jul 11 '17 at 09:53