Android: RoundRectShape: Modify corner radii

2019-01-29 12:32发布

问题:

I have a RoundRectShape that is drawn in a View's onDraw() function.

The corners of this shape are modified by any drag actions on this view through an overridden onTouchEvent function (which calls invalidate() to force the call to onDraw()).

When initialising variables in onDraw, Eclipse shows a warning saying Avoid object allocations during draw/layout operations (preallocate and reuse instead).

This issue is explained as follows:

You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations.

The way this is generally handled is to allocate objects up front and to reuse them for each drawing operation

To do this I obviously have to be able to modify the corner radii as set in the constructor. The RoundedRectShape class provides no setter (and I am pretty sure the related member variables are inaccessible).

I know it is a small object and a minor issue, but how can I change these corners without reinitializing the Object when the only method the class provides for setting the radii of the rounded corners is through the constructor?

Or is this just a case where doing the best thing will have to be replaced with doing what is possible?

Thanks,

P.S. Calling the constructor in the onTouchEvent() method will remove the warning but accomplishes absolutely nothing due to the fact that onDraw() is called every time through invalidate() anyway

回答1:

I think you don't need to use RoundRectShape at all. RoundRectShape is immutable so the only way to change its values is to use reflection. You can easily accomplish the same drawnings by calling Canvas.drawRoundRect(RectF rect, float rx, float ry, Paint paint) method directly without using RoundRectShape. Or you can look at RoundRectShape implementation and just use its code in your onDraw() method.

EDIT: The comments about RoundRectShape not being the right way to go and looking at the implementation were right. Following the implementation found a call to:

mPath.addRoundedRect() 

which has a variation allowing a float of corner radii as the input (Path.addRoundRect)

In answering the question:

Use a path instead of a shape as the variable and draw the new Rounded Rectangle to the path when necessary