Erweiterte Eingabestiftfunktionen

Android und ChromeOS bieten eine Vielzahl von APIs, mit denen Sie Apps erstellen können, die Ihren Nutzern einen außergewöhnlichen Eingabestift bieten. Die Klasse MotionEvent liefert Informationen zur Interaktion eines Eingabestifts mit dem Bildschirm, einschließlich Druck des Eingabestifts, Ausrichtung, Neigung, Mauszeiger und Handflächenerkennung. Grafiken mit niedriger Latenz und Bibliotheken für Bewegungsvorhersagen verbessern das Rendering von Eingabestiften auf dem Bildschirm, um ein natürliches Erscheinungsbild wie mit einem Stift und Papier zu ermöglichen.

MotionEvent

Die Klasse MotionEvent repräsentiert Interaktionen mit Nutzereingaben wie die Position und Bewegung der Touchpointer auf dem Bildschirm. Bei Eingabe über einen Eingabestift stellt MotionEvent auch Daten zu Druck, Ausrichtung, Neigung und dem Mauszeiger bereit.

Ereignisdaten

Fügen Sie den Komponenten einen pointerInput-Modifikator hinzu, um auf MotionEvent-Daten zuzugreifen:

@Composable
fun Greeting() {
    Text(
        text = "Hello, Android!", textAlign = TextAlign.Center, style = TextStyle(fontSize = 5.em),
        modifier = Modifier
            .pointerInput(Unit) {
                awaitEachGesture {
                    while (true) {
                        val event = awaitPointerEvent()
                        event.changes.forEach { println(it) }
                    }
                }
            },
    )
}

Ein MotionEvent-Objekt stellt Daten zu den folgenden Aspekten eines UI-Ereignisses bereit:

  • Aktionen: Physische Interaktion mit dem Gerät – Berühren des Bildschirms, Bewegen eines Mauszeigers über die Bildschirmoberfläche, Bewegen eines Zeigers über die Bildschirmoberfläche
  • Zeiger: Kennzeichnungen von Objekten, die mit dem Bildschirm interagieren – Finger, Eingabestift, Maus
  • Achse: Datentyp – x- und y-Koordinaten, Druck, Neigung, Ausrichtung und Hover (Entfernung)

Aktionen

Damit Sie die Unterstützung für Eingabestifte implementieren können, müssen Sie verstehen, welche Aktion der Nutzer ausführt.

MotionEvent bietet eine Vielzahl von ACTION-Konstanten, die Bewegungsereignisse definieren. Die wichtigsten Aktionen für den Eingabestift:

Aktion Beschreibung
ACTION_DOWN
ACTION_POINTER_DOWN
Der Zeiger hat den Bildschirm berührt.
ACTION_MOVE (Aktion_VERSCHIEBEN) Zeiger bewegt sich auf dem Bildschirm.
ACTION_UP
ACTION_POINTER_UP
Zeiger berührt den Bildschirm nicht mehr
AKTION_ABBRECHEN Wann der vorherige oder die aktuelle Bewegungssatz abgebrochen werden soll.

Deine App kann Aufgaben wie das Starten eines neuen Strichs, wenn ACTION_DOWN auftritt, den Strich mit ACTION_MOVE, zeichnen und ihn beenden, wenn ACTION_UP ausgelöst wird.

Die Gruppe der MotionEvent-Aktionen von ACTION_DOWN bis ACTION_UP für einen bestimmten Zeiger wird als Bewegungssatz bezeichnet.

Mauszeiger

Die meisten Bildschirme sind Multi-Touch-Funktionen: Das System weist jedem Finger, Eingabestift, jeder Maus und jedem anderen Zeigeobjekt, das mit dem Bildschirm interagiert, einen Zeiger zu. Mit einem Zeigerindex können Sie Achseninformationen für einen bestimmten Zeiger abrufen, z. B. die Position des ersten Fingers, der den Bildschirm berührt, oder der Position des zweiten Fingers.

Zeigerindexe reichen von null bis zur Anzahl der Zeiger, die von MotionEvent#pointerCount() abzüglich 1 zurückgegeben werden.

Auf die Achsenwerte der Zeiger kann mit der Methode getAxisValue(axis, pointerIndex) zugegriffen werden. Wenn der Zeigerindex weggelassen wird, gibt das System den Wert für den ersten Zeiger zurück, Zeiger Null (0).

MotionEvent-Objekte enthalten Informationen zum verwendeten Zeigertyp. Sie können den Zeigertyp abrufen, indem Sie die Zeigerindexe durchlaufen und die Methode getToolType(pointerIndex) aufrufen.

Weitere Informationen zu Zeigern finden Sie unter Multi-Touch-Gesten verarbeiten.

Eingabestift

Mit TOOL_TYPE_STYLUS können Sie nach Eingabestiften filtern:

val isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex)

Der Eingabestift kann auch melden, dass er als Radierer verwendet wird, mit TOOL_TYPE_ERASER:

val isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex)

Daten der Eingabestiftachse

ACTION_DOWN und ACTION_MOVE stellen die Achsendaten des Eingabestifts bereit, also x- und y-Koordinaten, Druck, Ausrichtung, Neigung und Mauszeiger.

Die MotionEvent API stellt getAxisValue(int) bereit, um den Zugriff auf diese Daten zu ermöglichen. Dabei steht der Parameter für eine der folgenden Achsenkennungen:

Axis Rückgabewert von getAxisValue()
AXIS_X X-Koordinate eines Bewegungsereignisses
AXIS_Y Y-Koordinate eines Bewegungsereignisses
AXIS_PRESSURE Auf einem Touchscreen oder Touchpad der Druck, der von einem Finger, einem Eingabestift oder einem anderen Zeiger ausgeübt wird. Bei Maus- oder Trackballs: 1, wenn die Haupttaste gedrückt wird, andernfalls 0.
AXIS_ORIENTATION Bei einem Touchscreen oder Touchpad die Ausrichtung eines Fingers, eines Eingabestifts oder eines anderen Zeigers relativ zur vertikalen Ebene des Geräts.
AXIS_TILT Der Neigungswinkel des Eingabestifts im Bogenmaß.
AXIS_DISTANCE Der Abstand des Eingabestifts zum Bildschirm.

MotionEvent.getAxisValue(AXIS_X) gibt beispielsweise die X-Koordinate für den ersten Zeiger zurück.

Weitere Informationen finden Sie unter Multi-Touch-Gesten bedienen.

Position

Sie können die x- und y-Koordinaten eines Zeigers mit den folgenden Aufrufen abrufen:

Zeichnung eines Eingabestifts auf dem Bildschirm mit den x- und y-Koordinaten
Abbildung 1. X- und Y-Bildschirmkoordinaten eines Eingabestiftzeigers

Luftdruck

Sie können den Druck des Zeigers mit MotionEvent#getAxisValue(AXIS_PRESSURE) oder mit MotionEvent#getPressure() für den ersten Zeiger abrufen.

Der Druckwert für Touchscreens oder Touchpads liegt zwischen 0 (kein Druck) und 1. Je nach Bildschirmkalibrierung können aber auch höhere Werte zurückgegeben werden.

Eingabe eines Eingabestifts, der ein Kontinuum des niedrigen bis hohen Drucks darstellt. Der Strich ist links schmal und schwach, was auf niedrigen Druck hindeutet. Der Strich wird von links nach rechts breiter und dunkler, bis er ganz rechts am breitesten und am dunkelsten wird, was auf den höchsten Druck hinweist.
Abbildung 2. Druckdarstellung: niedriger Druck links, hoher Druck rechts.

Ausrichtung

Die Ausrichtung gibt an, in welche Richtung der Eingabestift zeigt.

Die Zeigerausrichtung kann mit getAxisValue(AXIS_ORIENTATION) oder getOrientation() (für den ersten Zeiger) abgerufen werden.

Bei einem Eingabestift wird die Ausrichtung als Radiantwert zwischen 0 und pi (∂) im Uhrzeigersinn oder 0 bis -pi gegen den Uhrzeigersinn zurückgegeben.

Mithilfe der Ausrichtung kannst du einen realen Pinsel implementieren. Wenn der Eingabestift beispielsweise einen flachen Pinsel darstellt, hängt seine Breite von seiner Ausrichtung ab.

Abbildung 3: Eingabestift zeigt nach links etwa minus 0,57 Radiant.

Neigen

„Neigung“ gibt die Neigung des Eingabestifts relativ zum Bildschirm an.

Die Neigung gibt den positiven Winkel des Eingabestifts im Bogenmaß zurück, wobei Null senkrecht zum Bildschirm und ∂/2 flach auf der Oberfläche ist.

Der Neigungswinkel kann mit getAxisValue(AXIS_TILT) abgerufen werden (keine Verknüpfung für den ersten Zeiger).

Mithilfe der Neigung können reale Werkzeuge so nah wie möglich reproduziert werden, z. B. die Schattierung mit einem geneigten Bleistift nachzuahmen.

Eingabestift ist etwa 40 Grad von der Bildschirmoberfläche geneigt.
Abbildung 4: Eingabestift um etwa 0, 785 Radiant oder 45 Grad von der Senkrechten geneigt.

Mauszeiger hierher bewegen

Die Entfernung des Eingabestifts zum Bildschirm kann mit getAxisValue(AXIS_DISTANCE) abgerufen werden. Die Methode gibt einen Wert von 0,0 (Kontakt mit dem Bildschirm) zu höheren Werten zurück, wenn sich der Eingabestift vom Bildschirm entfernt. Der Abstand zwischen dem Bildschirm und der Spitze des Eingabestifts hängt vom Hersteller des Bildschirms und des Eingabestifts ab. Da Implementierungen variieren können, verlassen Sie sich für anwendungskritische Funktionen nicht auf präzise Werte.

Wenn du den Eingabestift bewegst, kannst du eine Vorschau der Größe des Pinsels ansehen oder angeben, dass eine Schaltfläche ausgewählt wird.

Abbildung 5: Eingabestift, der über einem Bildschirm schwebt. Die App reagiert, obwohl der Eingabestift die Displayoberfläche nicht berührt.

Hinweis:Die Funktion „Compose“ bietet Modifikatoren, die sich auf den interaktiven Status von UI-Elementen auswirken:

  • hoverable: Konfigurieren Sie die Komponente so, dass sie mit Zeiger-Eingabe- und -Exit-Ereignissen bewegt werden kann.
  • indication: Zeichnet visuelle Effekte für diese Komponente bei Interaktionen.

Ablehnen des Palms, Navigation und unerwünschte Eingaben

Manchmal werden unerwünschte Berührungen registriert, z. B. wenn ein Nutzer seine Hand auf dem Bildschirm ablehnt, um ihn beim Schreiben zu unterstützen. Die Palm-Ablehnung ist ein Mechanismus, der dieses Verhalten erkennt und Sie darüber informiert, dass der letzte MotionEvent-Satz abgebrochen werden soll.

Daher müssen Sie einen Verlauf der Nutzereingaben speichern, damit die unerwünschten Berührungen vom Bildschirm entfernt und die legitimen Nutzereingaben neu gerendert werden können.

ACTION_CANCEL und FLAG_CANCELED

ACTION_CANCEL und FLAG_CANCELED sollen Sie darüber informieren, dass der vorherige MotionEvent-Satz vom letzten ACTION_DOWN abgebrochen werden soll. So können Sie beispielsweise den letzten Strich für eine Zeichen-App für einen bestimmten Zeiger rückgängig machen.

AKTION_ABBRECHEN

In Android 1.0 (API-Level 1) hinzugefügt

ACTION_CANCEL gibt an, dass der vorherige Satz von Bewegungsereignissen abgebrochen werden soll.

ACTION_CANCEL wird ausgelöst, wenn eines der folgenden Elemente erkannt wird:

  • Touch-Gesten für die Navigation
  • Ablehnung der Handfläche

Wenn ACTION_CANCEL ausgelöst wird, sollten Sie den aktiven Cursor mit getPointerId(getActionIndex()) identifizieren. Entfernen Sie dann den mit diesem Zeiger erstellten Strich aus dem Eingabeverlauf und rendern Sie die Szene erneut.

FLAG_ABGEBROCHEN

In Android 13 (API-Level 33) hinzugefügt

FLAG_CANCELED gibt an, dass der nach oben gerichtete Zeiger eine unbeabsichtigte Berührung des Nutzers war. Das Flag wird normalerweise gesetzt, wenn der Nutzer versehentlich den Bildschirm berührt, z. B. wenn er das Gerät hält oder die Handfläche auf den Bildschirm legt.

So greifen Sie auf den Flag-Wert zu:

val cancel = (event.flags and FLAG_CANCELED) == FLAG_CANCELED

Wenn das Flag gesetzt ist, müssen Sie die letzte Einstellung für MotionEvent, ausgehend vom letzten ACTION_DOWN von diesem Zeiger, rückgängig machen.

Wie ACTION_CANCEL kann der Zeiger mit getPointerId(actionIndex) gefunden werden.

Abbildung 6: Durch die Eingabe des Eingabestifts und die Berührung mit der Handfläche werden MotionEvent-Sets erstellt. Touchbedienung wird abgebrochen und Display wird neu gerendert.

Vollbild-, Rand-zu-Rand- und Navigationsgesten

Wenn eine App im Vollbildmodus ist und interaktive Elemente am Rand enthält, wie z. B. den Canvas einer Zeichen- oder Notiz-App, kann das Wischen vom unteren Bildschirmrand zum Aufrufen der Navigation oder zum Verschieben der App in den Hintergrund zu einer unerwünschten Berührung des Canvas führen.

Abbildung 7: Wischen Sie mit einer Wischgeste, um eine App in den Hintergrund zu verschieben.

Um zu verhindern, dass durch Gesten unerwünschte Berührungen in deiner App ausgelöst werden, kannst du Einsätze und ACTION_CANCEL nutzen.

Weitere Informationen finden Sie im Abschnitt Palmenablehnung, Navigation und unerwünschte Eingaben.

Mit der Methode setSystemBarsBehavior() und BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE von WindowInsetsController kannst du verhindern, dass Navigationsgesten unerwünschte Touch-Ereignisse verursachen:

// Configure the behavior of the hidden system bars.
windowInsetsController.systemBarsBehavior =
    WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE

Weitere Informationen zur Verwaltung von Einfügungen und Touch-Gesten finden Sie unter:

Niedrige Latenz

Die Latenz ist die Zeit, die Hardware, System und Anwendung für die Verarbeitung und das Rendern von Nutzereingaben benötigen.

Latenz = Eingabeverarbeitung von Hardware und Betriebssystem + App-Verarbeitung + Zusammensetzung des Systems

  • Hardware-Rendering
Die Latenz führt dazu, dass der gerenderte Strich hinter der Eingabestiftposition zurückliegt. Die Lücke zwischen dem gerenderten Strich und der Position des Eingabestifts stellt die Latenz dar.
Abbildung 8. Die Latenz führt dazu, dass der gerenderte Strich hinter der Eingabestiftposition zurückliegt.

Quelle der Latenz

  • Eingabestift bei Touchscreen registrieren (Hardware): Erste kabellose Verbindung, wenn der Eingabestift und das Betriebssystem kommunizieren, um registriert und synchronisiert zu werden.
  • Rate der Berührungsabtastung (Hardware): Die Häufigkeit, mit der ein Touchscreen pro Sekunde prüft, ob ein Zeiger die Oberfläche berührt. Der Bereich liegt zwischen 60 und 1.000 Hz.
  • Eingabeverarbeitung (App): Anwenden von Farben, grafischen Effekten und Transformationen auf Nutzereingaben.
  • Grafikrendering (Betriebssystem und Hardware): Pufferaustausch, Hardwareverarbeitung

Grafik mit niedriger Latenz

Die Jetpack-Grafikbibliothek mit niedriger Latenz verkürzt die Verarbeitungszeit zwischen Nutzereingabe und Bildschirmrendering.

Die Bibliothek reduziert die Verarbeitungszeit, indem sie das Multi-Zwischenspeicher-Rendering vermeidet und eine Front-Puffer-Rendering-Technik nutzt, was bedeutet, dass direkt auf den Bildschirm geschrieben wird.

Frontbuffer-Rendering

Der Front-Zwischenspeicher ist der Arbeitsspeicher, den der Bildschirm für das Rendern verwendet. Es ist die beste Möglichkeit, Apps direkt auf dem Bildschirm zu zeichnen. Die Bibliothek mit niedriger Latenz ermöglicht es Apps, direkt im Front-Zwischenspeicher zu rendern. Dies verbessert die Leistung, indem verhindert wird, dass Zwischenspeicher gewechselt wird, was bei einem regulären Rendering mit mehreren Zwischenspeichern oder beim Rendering mit Doppelpuffern vorkommen kann (dies ist der häufigste Fall).

Die App schreibt in den Bildschirmzwischenspeicher und liest aus dem Bildschirmzwischenspeicher.
Abbildung 9. Front-buffer-Rendering.
Die App schreibt in den Multi-Zwischenspeicher, der dann mit dem Bildschirmpuffer ausgetauscht wird. Die App liest aus dem Bildschirmzwischenspeicher.
Abbildung 10. Rendering mit mehreren Zwischenspeichern.

Obwohl das Frontpuffer-Rendering eine gute Technik zum Rendern eines kleinen Bereichs des Bildschirms ist, ist es nicht für die Aktualisierung des gesamten Bildschirms vorgesehen. Beim Frontbuffer-Rendering rendert die App Inhalte in einem Zwischenspeicher, aus dem die Anzeige liest. Dies kann zum Rendern oder Reißen von Artefakten führen(siehe unten).

Die Bibliothek mit niedriger Latenz ist ab Android 10 (API-Level 29) und auf ChromeOS-Geräten mit Android 10 (API-Level 29) und höher verfügbar.

Abhängigkeiten

Die Bibliothek mit niedriger Latenz stellt die Komponenten für die Front-Zwischenspeicher-Rendering-Implementierung bereit. Die Bibliothek wird als Abhängigkeit in der Moduldatei build.gradle der Anwendung hinzugefügt:

dependencies {
    implementation "androidx.graphics:graphics-core:1.0.0-alpha03"
}

GLFrontBufferRenderer-Callbacks

Die Bibliothek mit niedriger Latenz enthält die Schnittstelle GLFrontBufferRenderer.Callback, die die folgenden Methoden definiert:

Die Bibliothek mit niedriger Latenz ist hinsichtlich der Art von Daten, die Sie mit GLFrontBufferRenderer verwenden, nicht unvoreingenommen.

Die Bibliothek verarbeitet die Daten jedoch als einen Strom aus Hunderten von Datenpunkten. Daher sollten Sie Ihre Daten so gestalten, dass die Arbeitsspeichernutzung und -zuweisung optimiert wird.

Rückrufe

Implementieren Sie GLFrontBufferedRenderer.Callback und überschreiben Sie onDrawFrontBufferedLayer() und onDrawDoubleBufferedLayer(), um Rendering-Callbacks zu aktivieren. GLFrontBufferedRenderer verwendet die Callbacks, um die Daten optimal zu rendern.

val callback = object: GLFrontBufferedRenderer.Callback<DATA_TYPE> {
   override fun onDrawFrontBufferedLayer(
       eglManager: EGLManager,
       bufferInfo: BufferInfo,
       transform: FloatArray,
       param: DATA_TYPE
   ) {
       // OpenGL for front buffer, short, affecting small area of the screen.
   }
   override fun onDrawMultiDoubleBufferedLayer(
       eglManager: EGLManager,
       bufferInfo: BufferInfo,
       transform: FloatArray,
       params: Collection<DATA_TYPE>
   ) {
       // OpenGL full scene rendering.
   }
}
Instanz von GLFrontBufferedRenderer deklarieren

Bereiten Sie das GLFrontBufferedRenderer vor. Geben Sie dazu das SurfaceView und die Callbacks an, die Sie zuvor erstellt haben. GLFrontBufferedRenderer optimiert das Rendering im Front- und Double-Zwischenspeicher mithilfe Ihrer Callbacks:

var glFrontBufferRenderer = GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks)
Rendering

Das Front-Zwischenspeicher-Rendering beginnt, wenn Sie die Methode renderFrontBufferedLayer() aufrufen, wodurch der onDrawFrontBufferedLayer()-Callback ausgelöst wird.

Das Rendering mit doppelter Zwischenspeicherung wird fortgesetzt, wenn Sie die Funktion commit() aufrufen, die den Callback onDrawMultiDoubleBufferedLayer() auslöst.

Im folgenden Beispiel wird der Prozess in den Front-Zwischenspeicher (schnelles Rendering) gerendert, wenn der Nutzer beginnt, auf dem Bildschirm zu zeichnen (ACTION_DOWN) und den Zeiger umherbewegt (ACTION_MOVE). Der Prozess wird in den doppelten Zwischenspeicher gerendert, wenn der Zeiger die Oberfläche des Bildschirms verlässt (ACTION_UP).

Mit requestUnbufferedDispatch() können Sie festlegen, dass das Eingabesystem keine Bewegungsereignisse in Batches aufnimmt, sondern sie liefert, sobald sie verfügbar sind:

when (motionEvent.action) {
   MotionEvent.ACTION_DOWN -> {
       // Deliver input events as soon as they arrive.
       view.requestUnbufferedDispatch(motionEvent)
       // Pointer is in contact with the screen.
       glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
   }
   MotionEvent.ACTION_MOVE -> {
       // Pointer is moving.
       glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
   }
   MotionEvent.ACTION_UP -> {
       // Pointer is not in contact in the screen.
       glFrontBufferRenderer.commit()
   }
   MotionEvent.CANCEL -> {
       // Cancel front buffer; remove last motion set from the screen.
       glFrontBufferRenderer.cancel()
   }
}

Tipps zum Rendern

Dos

Kleine Bildschirmbereiche, Handschrift, Zeichnen, Skizzieren

Don'ts

Vollbildaktualisierung, Schwenken, Zoomen. Dies kann zum Zerreißen führen.

Reißend

Das Zerreißen erfolgt, wenn der Bildschirm aktualisiert wird, während der Bildschirmzwischenspeicher gleichzeitig geändert wird. Ein Teil des Bildschirms zeigt neue Daten, ein anderer zeigt alte Daten.

Der obere und untere Bereich des Android-Bildes sind falsch ausgerichtet, da beim Aktualisieren des Bildschirms ein Aufreißen auftritt.
Abbildung 11. Zurückziehen, wenn Bildschirm von oben nach unten aktualisiert wird.

Bewegungsvorhersage

Die Jetpack-Bewegungsvorhersagebibliothek reduziert die wahrgenommene Latenz, da der Strichpfad des Nutzers geschätzt und dem Renderer temporäre, künstliche Punkte bereitgestellt werden.

Die Bibliothek für Bewegungsvorhersagen erhält echte Nutzereingaben als MotionEvent-Objekte. Die Objekte enthalten Informationen über x- und y-Koordinaten, den Druck und die Zeit, die vom Bewegungsvorhersager verwendet werden, um zukünftige MotionEvent-Objekte vorherzusagen.

Vorhergesagte MotionEvent-Objekte sind nur Schätzungen. Vorhergesagte Ereignisse können die empfundene Latenz reduzieren, aber vorhergesagte Daten müssen nach dem Empfang durch tatsächliche MotionEvent-Daten ersetzt werden.

Die Bibliothek für Bewegungsvorhersagen ist ab Android 4.4 (API-Level 19) und auf ChromeOS-Geräten mit Android 9 (API-Level 28) und höher verfügbar.

Die Latenz führt dazu, dass der gerenderte Strich hinter der Eingabestiftposition zurückliegt. Die Lücke zwischen Strich und Eingabestift wird durch Vorhersagepunkte gefüllt. Die verbleibende Lücke ist die wahrgenommene Latenz.
Abbildung 12. Durch Bewegungsvorhersagen reduzierte Latenz.

Abhängigkeiten

Die Bibliothek für die Bewegungsvorhersage implementiert die Vorhersagefunktionen. Die Bibliothek wird als Abhängigkeit in der Moduldatei build.gradle der Anwendung hinzugefügt:

dependencies {
    implementation "androidx.input:input-motionprediction:1.0.0-beta01"
}

Implementierung

Die Bewegungsvorhersagebibliothek enthält die MotionEventPredictor-Schnittstelle, mit der die folgenden Methoden definiert werden:

  • record(): Speichert MotionEvent-Objekte als Datensatz der Nutzeraktionen
  • predict(): gibt eine vorhergesagte MotionEvent zurück
Instanz von MotionEventPredictor deklarieren
var motionEventPredictor = MotionEventPredictor.newInstance(view)
Den Predictor mit Daten versorgen
motionEventPredictor.record(motionEvent)
Vorhersage

when (motionEvent.action) {
   MotionEvent.ACTION_MOVE -> {
       val predictedMotionEvent = motionEventPredictor?.predict()
       if(predictedMotionEvent != null) {
            // use predicted MotionEvent to inject a new artificial point
       }
   }
}

Tipps zur Bewegungsvorhersage

Dos

Entfernen Sie Vorhersagepunkte, wenn ein neuer vorhergesagter Punkt hinzugefügt wird.

Don'ts

Verwenden Sie für das endgültige Rendering keine Vorhersagepunkte.

Notizen-Apps

Über ChromeOS können in deiner App bestimmte Aktionen zum Erstellen von Notizen deklariert werden.

Informationen zum Registrieren einer App als Notizen-App unter ChromeOS finden Sie unter Eingabekompatibilität.

Informationen zum Registrieren einer App als Notizen-App auf Android finden Sie unter Notizen-App erstellen.

Mit Android 14 (API-Level 34) wurde der Intent ACTION_CREATE_NOTE eingeführt, mit dem Ihre App Notizen auf dem Sperrbildschirm starten kann.

Digitale Tintenerkennung mit ML Kit

Mit der digitalen Tintenerkennung von ML Kit kann Ihre App handschriftlichen Text in Hunderten von Sprachen auf einer digitalen Oberfläche erkennen. Sie können auch Skizzen klassifizieren.

ML Kit bietet die Klasse Ink.Stroke.Builder zum Erstellen von Ink-Objekten, die von Modellen für maschinelles Lernen verarbeitet werden können, um Handschrift in Text umzuwandeln.

Zusätzlich zur Handschrifterkennung kann das Modell Gesten wie Löschen und Einkreisen erkennen.

Weitere Informationen finden Sie unter Digitale Tintenerkennung.

Zusätzliche Ressourcen

Entwicklerleitfäden

Codelabs