ViewStrokeRenderer
public final class ViewStrokeRenderer
Helps developers using Android Views to draw androidx.ink.strokes.Stroke objects in their UI, in an easier way than using CanvasStrokeRenderer directly. Construct this once for your View and reuse it during each View.onDraw call.
This utility is valid as long as View.onDraw
-
Does not call
Canvas.setMatrix. -
Does not modify
Canvastransform state prior to callingdrawWithStrokes. -
Does not use
android.graphics.RenderEffect, either setting it on thisViewor a subview usingView.setRenderEffect, or by callingCanvas.drawRenderNodeusing aandroid.graphics.RenderNodethat has been configured withandroid.graphics.RenderNode.setRenderEffect. Developers who want to useandroid.graphics.RenderEffectin conjunction withandroidx.ink.strokes.Strokerendering must useCanvasStrokeRenderer.drawdirectly.
Example:
class MyView(context: Context) : View(context) {
private val viewStrokeRenderer = ViewStrokeRenderer(myCanvasStrokeRenderer, this)
override fun onDraw(canvas: Canvas) {
viewStrokeRenderer.drawWithStrokes(canvas) { scope ->
canvas.scale(myZoomLevel)
canvas.rotate(myRotation)
canvas.translate(myPanX, myPanY)
scope.drawStroke(myStroke)
// Draw other objects including more strokes, apply more transformations, etc.
}
}
}
Summary
Public constructors |
|---|
ViewStrokeRenderer( |
Public methods |
|
|---|---|
final void |
drawWithStrokes(Kotlin developers should call this at the beginning of |
final void |
drawWithStrokes(Java developers should call this at the beginning of |
Public constructors
ViewStrokeRenderer
public ViewStrokeRenderer(
@NonNull CanvasStrokeRenderer canvasStrokeRenderer,
@NonNull View view
)
Public methods
drawWithStrokes
public final void drawWithStrokes(
@NonNull Canvas canvas,
@NonNull Function1<@NonNull StrokeDrawScope, Unit> block
)
Kotlin developers should call this at the beginning of View.onDraw and perform their Canvas manipulations within its scope.
For example:
viewStrokeRenderer.drawWithStrokes(canvas) { scope ->
canvas.scale(...) // or concat, or translate, or rotate, etc.
scope.drawStroke(stroke)
// Repeat with other strokes, draw other things to the canvas, etc.
}Java callers should prefer to use the non-inline overload of drawWithStrokes with a non-capturing lambda or an object that is allocated once and reused.
drawWithStrokes
public final void drawWithStrokes(
@NonNull Canvas canvas,
@NonNull Function2<@NonNull Canvas, @NonNull StrokeDrawScope, Unit> block
)
Java developers should call this at the beginning of View.onDraw and perform their Canvas manipulations within its scope.
The structure of the callback in this non-inline version makes it easier for Java callers to write performant code, since forwarding the value of canvas allows a lambda to be non-capturing, thereby avoiding an allocation of the lambda on every frame.
For example:
viewStrokeRenderer.drawWithStrokes(canvas, (scopedCanvas, scope) -> {
// Make sure to use `scopedCanvas` rather than `canvas` in this lambda!
scopedCanvas.scale(...); // or concat, or translate, or rotate, etc.
scope.drawStroke(stroke);
// Repeat with other strokes, draw other things to the canvas, etc.
});
Alternatively, the callback could be an object that is allocated once and reused.
Kotlin callers should prefer to use the inline overload of drawWithStrokes, as it better guarantees that the lambda argument will not cause an allocation.