InProgressStrokesView
@UiThread
public final class InProgressStrokesView extends FrameLayout
| java.lang.Object | ||||
| ↳ | android.view.View | |||
| ↳ | android.view.ViewGroup | |||
| ↳ | android.widget.FrameLayout | |||
| ↳ | androidx.ink.authoring.InProgressStrokesView |
Displays in-progress ink strokes as MotionEvent user inputs are provided to it.
For a Jetpack Compose equivalent which also provides a default input handler, see androidx.ink.authoring.compose.InProgressStrokes instead.
The visual styles of strokes are highly customizable by passing the appropriate Brush to startStroke, but if that declarative style specification is not rich enough and instead some more detailed programmatic logic is necessary, consider using InProgressShapesView instead.
Summary
Public constructors |
|---|
InProgressStrokesView( |
Public methods |
|
|---|---|
final void |
Add a listener to be notified when strokes are finished. |
final boolean |
addToStroke(Add |
final void |
addToStroke(Add input data from a |
final void |
addToStroke(Add input data, from a particular pointer within a |
final boolean |
cancelStroke(@NonNull MotionEvent event, int pointerId)Cancel the corresponding in-progress stroke with |
final void |
cancelStroke(@NonNull InProgressStrokeId strokeId, MotionEvent event)Cancel the building of a stroke. |
final void |
Cancel all in-progress strokes. |
final void |
Removes all listeners that had previously been added with |
final void |
Eagerly initialize rather than waiting for the first stroke to be drawn. |
final boolean |
finishStroke(@NonNull MotionEvent event, int pointerId)Finish the corresponding in-progress stroke with |
final void |
finishStroke(Complete the building of a stroke, with the last input data coming from a |
final void |
finishStroke(Complete the building of a stroke, with the last input data coming from a particular pointer of a |
final @NonNull Map<@NonNull InProgressStrokeId, @NonNull Stroke> |
Returns all the finished strokes that are still being rendered by this view, with map iteration order in the z-order that the strokes are being rendered, from back to front. |
final CountingIdlingResource |
Allows a test to easily wait until all in-progress strokes are completed and handed off. |
final Path |
Denote an area of this |
final @NonNull Matrix |
The transform matrix to convert |
final @NonNull TextureBitmapStore |
|
final boolean |
Returns true if there are any in-progress strokes. |
final void |
removeFinishedStrokes(@NonNull Set<@NonNull InProgressStrokeId> strokeIds)Stop this view from rendering the strokes with the given IDs. |
final void |
Removes a listener that had previously been added with |
final void |
Allows a test to easily wait until all in-progress strokes are completed and handed off. |
final void |
setMaskPath(Path <set-?>)Denote an area of this |
final void |
setMotionEventToViewTransform(@NonNull Matrix <set-?>)The transform matrix to convert |
final void |
|
final @NonNull InProgressStrokeId |
startStroke(Start building a stroke with the provided |
final @NonNull InProgressStrokeId |
startStroke(Start building a stroke using a particular pointer within a |
Protected methods |
|
|---|---|
void |
|
void |
Inherited methods |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Public constructors
InProgressStrokesView
public InProgressStrokesView(
@NonNull Context context,
AttributeSet attrs,
@AttrRes int defStyleAttr
)
Public methods
addFinishedStrokesListener
public final void addFinishedStrokesListener(
@NonNull InProgressStrokesFinishedListener listener
)
Add a listener to be notified when strokes are finished. These strokes will continue to be rendered within this view until removeFinishedStrokes is called. All of the strokes that have been delivered to listeners but have not yet been removed with removeFinishedStrokes are available through getFinishedStrokes.
addToStroke
public final boolean addToStroke(
@NonNull MotionEvent event,
int pointerId,
MotionEvent prediction
)
Add event data for pointerId to the corresponding in-progress stroke, if present. The stroke must have been started with an overload of startStroke that accepts a MotionEvent.
| Parameters | |
|---|---|
@NonNull MotionEvent event |
the next |
int pointerId |
the index of the relevant pointer in the |
MotionEvent prediction |
optional predicted |
| Returns | |
|---|---|
boolean |
Whether the pointer corresponds to an in-progress stroke. |
addToStroke
public final void addToStroke(
@NonNull StrokeInputBatch inputs,
@NonNull InProgressStrokeId strokeId,
@NonNull StrokeInputBatch prediction
)
Add input data from a StrokeInputBatch to an existing stroke. The stroke must have been started with an overload of startStroke that accepts a StrokeInput.
| Parameters | |
|---|---|
@NonNull StrokeInputBatch inputs |
The next |
@NonNull InProgressStrokeId strokeId |
The |
@NonNull StrokeInputBatch prediction |
Predicted |
addToStroke
public final void addToStroke(
@NonNull MotionEvent event,
int pointerId,
@NonNull InProgressStrokeId strokeId,
MotionEvent prediction
)
Add input data, from a particular pointer within a MotionEvent, to an existing stroke. The stroke must have been started with an overload of startStroke that accepts a MotionEvent.
| Parameters | |
|---|---|
@NonNull MotionEvent event |
The next |
int pointerId |
The identifier of the pointer within |
@NonNull InProgressStrokeId strokeId |
The |
MotionEvent prediction |
Predicted |
cancelStroke
public final boolean cancelStroke(@NonNull MotionEvent event, int pointerId)
Cancel the corresponding in-progress stroke with event data for pointerId, if present. The stroke must have been started with an overload of startStroke that accepts a MotionEvent.
| Parameters | |
|---|---|
@NonNull MotionEvent event |
The |
int pointerId |
the id of the relevant pointer in the |
| Returns | |
|---|---|
boolean |
Whether the pointer corresponded to an in-progress stroke. |
cancelStroke
public final void cancelStroke(@NonNull InProgressStrokeId strokeId, MotionEvent event)
Cancel the building of a stroke. It will no longer be visible within this InProgressStrokesView, and no completed Stroke object will come through InProgressStrokesFinishedListener.
This is typically done for one of three reasons:
-
A
MotionEventwithMotionEvent.getActionMaskedofMotionEvent.ACTION_CANCEL. This tends to be when an entire gesture has been canceled, for example when a parentandroid.view.Viewusesandroid.view.ViewGroup.onInterceptTouchEventto intercept and handle the gesture itself. -
A
MotionEventwithMotionEvent.getFlagscontainingMotionEvent.FLAG_CANCELED. This tends to be when the system has detected an unintentional touch, such as from the user resting their palm on the screen while writing or drawing, after some events from that unintentional pointer have already been delivered. -
An app's business logic reinterprets a gesture previously used for inking as something else, and the earlier inking may be seen as unintentional. For example, an app that uses single-pointer gestures for inking and dual-pointer gestures for pan/zoom/rotate will start inking when the first pointer goes down, but when the second pointer goes down it may want to cancel the stroke from the first pointer rather than leave the small ink marks on the screen.
Does nothing if a stroke with the given strokeId is not in progress.
| Parameters | |
|---|---|
@NonNull InProgressStrokeId strokeId |
The |
MotionEvent event |
The |
cancelUnfinishedStrokes
public final void cancelUnfinishedStrokes()
Cancel all in-progress strokes.
clearFinishedStrokesListeners
public final void clearFinishedStrokesListeners()
Removes all listeners that had previously been added with addFinishedStrokesListener.
eagerInit
public final void eagerInit()
Eagerly initialize rather than waiting for the first stroke to be drawn. Since initialization can be somewhat heavyweight, doing this as soon as it's likely for the user to start drawing can prevent initialization from introducing latency to the first stroke.
finishStroke
public final boolean finishStroke(@NonNull MotionEvent event, int pointerId)
Finish the corresponding in-progress stroke with event data for pointerId, if present. The stroke must have been started with an overload of startStroke that accepts a MotionEvent.
| Parameters | |
|---|---|
@NonNull MotionEvent event |
the last |
int pointerId |
the id of the relevant pointer in the |
| Returns | |
|---|---|
boolean |
Whether the pointer corresponded to an in-progress stroke. |
finishStroke
public final void finishStroke(
@NonNull StrokeInput input,
@NonNull InProgressStrokeId strokeId
)
Complete the building of a stroke, with the last input data coming from a StrokeInput. The stroke must have been started with an overload of startStroke that accepts a StrokeInput.
| Parameters | |
|---|---|
@NonNull StrokeInput input |
The last |
@NonNull InProgressStrokeId strokeId |
The |
finishStroke
public final void finishStroke(
@NonNull MotionEvent event,
int pointerId,
@NonNull InProgressStrokeId strokeId
)
Complete the building of a stroke, with the last input data coming from a particular pointer of a MotionEvent. The stroke must have been started with an overload of startStroke that accepts a MotionEvent.
When the stroke no longer needs to be rendered by this InProgressStrokesView and can instead be rendered anywhere in the android.view.View hierarchy using CanvasStrokeRenderer, the resulting Stroke object will be passed to the InProgressStrokesFinishedListener instances registered with this InProgressStrokesView using addFinishedStrokesListener.
Does nothing if a stroke with the given strokeId is not in progress.
| Parameters | |
|---|---|
@NonNull MotionEvent event |
The last |
int pointerId |
The identifier of the pointer within |
@NonNull InProgressStrokeId strokeId |
The |
getFinishedStrokes
public final @NonNull Map<@NonNull InProgressStrokeId, @NonNull Stroke> getFinishedStrokes()
Returns all the finished strokes that are still being rendered by this view, with map iteration order in the z-order that the strokes are being rendered, from back to front. This is the same order that strokes were started with startStroke. The IDs of these strokes should be passed to removeFinishedStrokes when they are handed off to another view.
getInProgressStrokeCounter
public final CountingIdlingResource getInProgressStrokeCounter()
Allows a test to easily wait until all in-progress strokes are completed and handed off. There is no reason to set this in non-test code.
getMaskPath
public final Path getMaskPath()
Denote an area of this InProgressStrokesView where no ink should be visible. A value of null indicates that strokes will be visible anywhere they are drawn. This is useful for UI elements that float on top of (in Z order) the drawing surface - without this, a user would be able to draw in-progress ("wet") strokes on top of those UI elements, but then when the stroke is finished, it will appear as a dry stroke underneath of the UI element. If this mask is set to the shape and position of the floating UI element, then the ink will never be rendered in that area, making it appear as if it's being drawn underneath the UI element.
This technique is most convincing when the UI element is opaque. Often there are parts of the UI element that are translucent, such as drop shadows, or anti-aliasing along the edges. The result will look a little different between wet and dry strokes for those cases, but it can be a worthwhile tradeoff compared to the alternative of drawing wet strokes on top of that UI element.
Note that this parameter does not affect the contents of the strokes at all, nor how they appear when drawn in a separate composable after InProgressStrokesFinishedListener.onStrokesFinished is called - just how the strokes appear when they are still in progress in this view.
getMotionEventToViewTransform
public final @NonNull Matrix getMotionEventToViewTransform()
The transform matrix to convert MotionEvent coordinates, as passed to startStroke, addToStroke, and finishStroke, into coordinates of this InProgressStrokesView for rendering. Defaults to the identity matrix, for the recommended case where InProgressStrokesView exactly overlays the android.view.View that has the touch listener from which MotionEvent instances are being forwarded.
getTextureBitmapStore
public final @NonNull TextureBitmapStore getTextureBitmapStore()
TextureBitmapStore used to create the CanvasStrokeRenderer.
By default, this is a no-op implementation that does not load any brush textures. The factory functions are called when the renderer is initialized, so if this will be changed to something that does load and store texture images, it must be set before the first call to startStroke or eagerInit.
hasUnfinishedStrokes
public final boolean hasUnfinishedStrokes()
Returns true if there are any in-progress strokes.
removeFinishedStrokes
public final void removeFinishedStrokes(@NonNull Set<@NonNull InProgressStrokeId> strokeIds)
Stop this view from rendering the strokes with the given IDs.
This should be called in the same UI thread run loop (HWUI frame) as when the strokes start being rendered elsewhere in the view hierarchy. This means they are saved in a location where they will be picked up in a view's next call to onDraw, and that view's invalidate method has been called. If these two operations are not done within the same UI thread run loop (usually side by side - see example below), then there will be brief rendering errors - either a visual gap where the stroke is not drawn during a frame, or a double draw where the stroke is drawn twice and translucent strokes appear more opaque than they should.
removeFinishedStrokesListener
public final void removeFinishedStrokesListener(
@NonNull InProgressStrokesFinishedListener listener
)
Removes a listener that had previously been added with addFinishedStrokesListener.
setInProgressStrokeCounter
public final void setInProgressStrokeCounter(CountingIdlingResource <set-?>)
Allows a test to easily wait until all in-progress strokes are completed and handed off. There is no reason to set this in non-test code.
setMaskPath
public final void setMaskPath(Path <set-?>)
Denote an area of this InProgressStrokesView where no ink should be visible. A value of null indicates that strokes will be visible anywhere they are drawn. This is useful for UI elements that float on top of (in Z order) the drawing surface - without this, a user would be able to draw in-progress ("wet") strokes on top of those UI elements, but then when the stroke is finished, it will appear as a dry stroke underneath of the UI element. If this mask is set to the shape and position of the floating UI element, then the ink will never be rendered in that area, making it appear as if it's being drawn underneath the UI element.
This technique is most convincing when the UI element is opaque. Often there are parts of the UI element that are translucent, such as drop shadows, or anti-aliasing along the edges. The result will look a little different between wet and dry strokes for those cases, but it can be a worthwhile tradeoff compared to the alternative of drawing wet strokes on top of that UI element.
Note that this parameter does not affect the contents of the strokes at all, nor how they appear when drawn in a separate composable after InProgressStrokesFinishedListener.onStrokesFinished is called - just how the strokes appear when they are still in progress in this view.
setMotionEventToViewTransform
public final void setMotionEventToViewTransform(@NonNull Matrix <set-?>)
The transform matrix to convert MotionEvent coordinates, as passed to startStroke, addToStroke, and finishStroke, into coordinates of this InProgressStrokesView for rendering. Defaults to the identity matrix, for the recommended case where InProgressStrokesView exactly overlays the android.view.View that has the touch listener from which MotionEvent instances are being forwarded.
setTextureBitmapStore
public final void setTextureBitmapStore(@NonNull TextureBitmapStore value)
TextureBitmapStore used to create the CanvasStrokeRenderer.
By default, this is a no-op implementation that does not load any brush textures. The factory functions are called when the renderer is initialized, so if this will be changed to something that does load and store texture images, it must be set before the first call to startStroke or eagerInit.
startStroke
public final @NonNull InProgressStrokeId startStroke(
@NonNull StrokeInput input,
@NonNull Brush brush,
@NonNull Matrix strokeToViewTransform
)
Start building a stroke with the provided input. This would typically be followed by many calls to addToStroke, and the sequence would end with a call to either finishStroke or cancelStroke.
In most circumstances, the startStroke overload that accepts a MotionEvent is more convenient. However, this overload using a StrokeInput is available for cases where the input data may not come directly from a MotionEvent, such as receiving events over a network connection. Using this function to start a stroke can only be followed by the StrokeInput variants of addToStroke and finishStroke for the same stroke.
If there is a way to request unbuffered dispatch from the source of the input data used here, equivalent to android.view.View.requestUnbufferedDispatch for unbuffered MotionEvent data, then be sure to request it for optimal performance.
| Parameters | |
|---|---|
@NonNull StrokeInput input |
The |
@NonNull Brush brush |
Brush specification for the stroke being started. Note that if stroke coordinate units (the |
@NonNull Matrix strokeToViewTransform |
The |
| Returns | |
|---|---|
@NonNull InProgressStrokeId |
The |
startStroke
public final @NonNull InProgressStrokeId startStroke(
@NonNull MotionEvent event,
int pointerId,
@NonNull Brush brush,
@NonNull Matrix motionEventToWorldTransform,
@NonNull Matrix strokeToWorldTransform
)
Start building a stroke using a particular pointer within a MotionEvent. This would typically be followed by many calls to addToStroke, and the sequence would end with a call to either finishStroke or cancelStroke.
In most circumstances, prefer to use this function over startStroke that accepts a StrokeInput. Using this function to start a stroke must only be followed by the MotionEvent variants of addToStroke and finishStroke for the same stroke.
For optimum performance, it is strongly recommended to call android.view.View.requestUnbufferedDispatch using event and the android.view.View that generated event alongside calling this function. When requested this way, unbuffered dispatch mode will automatically end when the gesture is complete.
| Parameters | |
|---|---|
@NonNull MotionEvent event |
The first |
int pointerId |
The identifier of the pointer within |
@NonNull Brush brush |
Brush specification for the stroke being started. Note that the overall scaling factor of |
@NonNull Matrix motionEventToWorldTransform |
The matrix that transforms |
@NonNull Matrix strokeToWorldTransform |
Allows an object-specific (stroke-specific) coordinate space to be defined in relation to the caller's "world" coordinate space. This defaults to the identity matrix, which is typical for many use cases at the time of stroke construction. In typical use cases, stroke coordinates and world coordinates may start to differ from one another after stroke creation as a particular stroke is manipulated within the world, e.g. it may be moved, scaled, or rotated relative to other content within an app's document. This matrix must be invertible. |
| Returns | |
|---|---|
@NonNull InProgressStrokeId |
The |
| Throws | |
|---|---|
IllegalArgumentException |
if |