setShadowLayer causes slow draw time in GridView?

2020-02-11 05:46发布

问题:

I'm currently working with a GridView containing ImageViews and would like shadows behind my images. There are potentially, say, 15 images visible in the grid at any time. Working under the assumption that I want my screen to render at 50fps to appear smooth, my math shows that I want the total draw time of each ImageView to be no worse than around 1.3ms.

I took a look at how Romain Guy was doing shadows in his Shelves app: http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java

That seemed to make sense, so I created the following class:

 public class ShadowImageView extends ImageView {
     private static final int SHADOW_RADIUS = 8;
     private static final int SHADOW_COLOR = 0x99000000;
     private static final Paint SHADOW_PAINT = new Paint();

     static {
         SHADOW_PAINT.setShadowLayer(SHADOW_RADIUS / 2.0f, 0.0f, 
             0.0f, SHADOW_COLOR);
         SHADOW_PAINT.setColor(0xFF000000);
         SHADOW_PAINT.setStyle(Paint.Style.FILL);
     }

     public ShadowImageView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }

     @Override
     public void onDraw(Canvas canvas) {
         final int containerWidth = getMeasuredWidth();
         final int containerHeight = getMeasuredHeight();

         canvas.drawRect(
                 SHADOW_RADIUS / 2.0f,
                 SHADOW_RADIUS / 2.0f,
                 containerWidth - SHADOW_RADIUS / 2.0f,
                 containerHeight - SHADOW_RADIUS / 2.0f,
                 SHADOW_PAINT);
     }
 }

(Obviously this just gives me black rectangles with shadows, but was enough for getting an initial guess on performance.)

Scrolling through the grid was pretty choppy, so I checked the draw times I was getting in Hierarchy Viewer: ~3.5ms per ImageView. This comes out to around 19fps at best.

If I remove the setShadowLayer() statement, however, Hierarchy Viewer shows draw times around 0.2ms per ImageView.

If I forget all about drawRect() and instead create a nine-patch with shadow edges, calling setBackgroundResource(R.drawable.my_nine_patch) in onDraw(), I see draw times around 1.5ms per ImageView.

Are there known performance issues using Paint with a shadowLayer? Am I doing something silly in the above code?