In viewbasierten Layouts müssen Sie die Berührungseingaben der Nutzer zusätzlich zu MotionEventPredictor auch in einem InProgressStrokesView verarbeiten.
Verwenden Sie die Methoden startStroke(), addToStroke() und finishStroke() der Klasse InProgressStrokesView, um eine optimale Zeichenleistung zu erzielen. Übergeben Sie MotionEvent-Objekte als Eingabe:
UI-Komponente einrichten
Fügen Sie für ansichtsbasierte Layouts
InProgressStrokesViewin Ihre Ansichtshierarchie ein.<FrameLayout> <ScrollView android:id="@+id/my_content" android:width="match_parent" android:height="match_parent" > <!-- Your content here. --> </ScrollView> <androidx.ink.authoring.InProgressStrokesView android:id="@+id/in_progress_strokes_view" android:width="match_parent" android:height="match_parent" /> </FrameLayout>Instanziieren
InProgressStrokesViewRufen Sie in der Methode
onCreate()Ihrer Aktivität oder Ihres Fragments eine Referenz zuInProgressStrokesViewab und legen Sie einen Touch-Listener fest, um Nutzereingaben zu verarbeiten.Innerhalb der [
onCreate()][ink-draw-include6]-Methode Ihrer Aktivität oder Ihres Fragments auf dieInProgressStrokesViewverweisen und eine Touch-Listener zum Verwalten von Nutzereingaben.class MyActivity : View.OnTouchListener { private lateinit var contentView: ScrollView private lateinit var inProgressStrokesView: InProgressStrokesView private lateinit var predictor: MotionEventPredictor // ... other variables override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) predictor = MotionEventPredictor.newInstance(contentView) contentView = findViewById(R.id.my_content) contentView.setOnTouchListener(touchListener) inProgressStrokesView = findViewById(R.id.in_progress_strokes_view) } // ... (touchListener implementation) }Touch-Ereignisse verarbeiten
Nachdem Sie die UI-Komponenten eingerichtet haben, können Sie das Zeichnen basierend auf Touch-Ereignissen starten.
MotionEventAktionInProgressStrokesView-MethodeBeschreibung
Strichrendering starten
Strich verlängern
Eingaben abschließen, um die Geometrie des Strichs fertigzustellen
Strich abbrechen
class MyActivity : View.OnTouchListener { private lateinit var contentView: ScrollView private lateinit var inProgressStrokesView: InProgressStrokesView private var pointerId = -1 private var strokeId: InProgressStrokeId? = null private lateinit var predictor: MotionEventPredictor override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) contentView = findViewById(R.id.my_content) predictor = MotionEventPredictor.create(contentView) contentView.setOnTouchListener(touchListener) inProgressStrokesView = findViewById(R.id.in_progress_strokes_view) } private val touchListener = { view: View, event: MotionEvent -> predictor.record(event) when (event.actionMasked) { MotionEvent.ACTION_DOWN -> { // First pointer - treat it as inking. view.requestUnbufferedDispatch(event) val pointerIndex = event.actionIndex pointerIdToStrokeId[event.getPointerId(pointerIndex)] = inProgressStrokesView.startStroke(event, pointerId) return true } MotionEvent.ACTION_POINTER_DOWN -> { val stroke = strokeId ?: return false inProgressStrokesView.cancelStroke(stroke, event) strokeId = null pointerId = -1 return false } MotionEvent.ACTION_MOVE -> { val predictedEvent = predictor.predict() try { for (pointerIndex in 0 until pointerCount) { val strokeId = pointerIdToStrokeId[event.getPointerId(pointerIndex)] ?: continue inProgressStrokesView.addToStroke(event, pointerId, strokeId, predictedEvent) } finally { predictedEvent?.recycle() } } } MotionEvent.ACTION_UP -> { val pointerIndex = event.actionIndex val strokeId = pointerIdToStrokeId[event.getPointerId(pointerIndex)] ?: return false inProgressStrokesView.finishStroke(event, pointerId, strokeId) return true } MotionEvent.ACTION_CANCEL -> { val pointerIndex = event.actionIndex val strokeId = pointerIdToStrokeId[event.getPointerId(pointerIndex)] ?: return false inProgressStrokesView.cancelStroke(strokeId, event) return true } } return false } }Abgeschlossene Striche verarbeiten
Nach
finishStroke()ist der Strich fast fertig. Der Strich wird vollständig verarbeitet und ist für Ihre Anwendung verfügbar, sobald keine anderen Striche mehr ausgeführt werden. So wird sichergestellt, dass alle Zeichenvorgänge abgeschlossen sind, bevor der Strich an den Client übergeben wird.Sie haben zwei Möglichkeiten, abgeschlossene Striche abzurufen:
- Implementieren Sie die Schnittstelle
InProgressStrokesFinishedListenerin Ihrer Aktivität oder Ihrem ViewModel und registrieren Sie den Listener mitInProgressStrokesView, indem SieaddFinishedStrokesListeneraufrufen. - Rufen Sie
InProgressStrokesView.getFinishedStrokes()auf, um alle abgeschlossenen Striche direkt abzurufen.
class MyActivity : ComponentActivity(), InProgressStrokesFinishedListener { ... private val finishedStrokesState = mutableStateOf(emptySet<Stroke>()) override fun onCreate(savedInstanceState: Bundle?) { ... inProgressStrokesView.addFinishedStrokesListener(this) } // ... (handle touch events) @UiThread override fun onStrokesFinished(strokes: Map<InProgressStrokeId, Stroke>) { finishedStrokesState.value += strokes.values inProgressStrokesView.removeFinishedStrokes(strokes.keys) } }Nachdem Sie die fertigen Striche abgerufen haben, können Sie sie mit
ViewStrokeRendererzeichnen:class DrawingView(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, ... } } }- Implementieren Sie die Schnittstelle