Mit dem Eingabestift können Nutzer bequem und punktgenau mit Apps interagieren, z. B. Notizen, Skizzen, Arbeiten mit Produktivitäts-Apps, zum Entspannen und für Spaß mit Spielen und Unterhaltungs-Apps.
Android und ChromeOS bieten eine Vielzahl von APIs, mit denen du Apps mit Eingabestift optimal nutzen kannst. Die Klasse MotionEvent
liefert Informationen zur Nutzerinteraktion mit dem Bildschirm, z. B. zum Druck des Eingabestifts, zur Ausrichtung, zur Neigung, zum Bewegen des Mauszeigers und zur Handflächenerkennung. Bibliotheken mit niedriger Latenz und Bewegungsvorhersagen verbessern das Rendern mit Eingabestiften auf dem Bildschirm und sorgen so für ein ganz natürliches Erlebnis mit Stift und Papier.
MotionEvent
Die Klasse MotionEvent
repräsentiert Nutzereingabeinteraktionen wie die Position und Bewegung von Touchpointern auf dem Bildschirm. Bei Eingabe des Eingabestifts zeigt MotionEvent
auch Daten zu Druck, Ausrichtung, Neigung und dem Mauszeiger an.
Ereignisdaten
Richten Sie für den Zugriff auf MotionEvent
-Daten in aufrufbasierten Apps einen onTouchListener ein:
Kotlin
val onTouchListener = View.OnTouchListener { view, event -> // Process motion event. }
Java
View.OnTouchListener listener = (view, event) -> { // Process motion event. };
Der Listener empfängt MotionEvent
-Objekte vom System, sodass Ihre App sie verarbeiten kann.
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 Zeigers über die Bildschirmoberfläche, Bewegen eines Zeigers über die Bildschirmoberfläche
- Zeiger: Kennungen von Objekten, die mit dem Bildschirm interagieren (Finger, Eingabestift, Maus)
- Achse: Datentyp – x- und y-Koordinaten, Druck, Neigung, Ausrichtung und Mouseover (Entfernung)
Aktionen
Um die Eingabestiftunterstützung zu implementieren, 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 sind:
Aktion | Beschreibung |
---|---|
ACTION_DOWN ACTION_POINTER_DOWN |
Zeiger hat Kontakt mit dem Bildschirm hergestellt. |
ACTION_MOVE (Aktionsverschiebung) | Zeiger bewegt sich auf dem Bildschirm. |
ACTION_UP ACTION_POINTER_UP |
Zeiger liegt nicht mehr auf dem Bildschirm |
AKTION_ABBRECHEN | Wenn eine vorherige oder aktuelle Bewegung abgebrochen werden soll. |
Ihre App kann verschiedene Aufgaben ausführen, z. B. das Starten eines neuen Strichs, wenn ACTION_DOWN
geschieht, das Zeichnen des Strichs mit ACTION_MOVE,
und das Fertigstellen des Strichs, 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.
Zeiger
Die meisten Bildschirme arbeiten mit Multi-Touch-Funktion: Das System weist jedem Finger, Eingabestift, jeder Maus oder einem 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 die Position des zweiten.
Zeigerindexe reichen von null bis die Anzahl der von MotionEvent#pointerCount()
zurückgegebenen Zeiger minus 1.
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 durch die Zeigerindexe iterieren und die Methode getToolType(pointerIndex)
aufrufen.
Weitere Informationen zu Zeigern finden Sie unter Multi-Touch-Gesten handhaben.
Eingabestift-Eingaben
Mit TOOL_TYPE_STYLUS
können Sie nach Eingabestifteingaben filtern:
Kotlin
val isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex)
Java
boolean isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex);
Der Eingabestift kann auch melden, dass er als Radierer mit TOOL_TYPE_ERASER
verwendet wird:
Kotlin
val isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex)
Java
boolean isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex);
Daten zur Eingabestiftachse
ACTION_DOWN
und ACTION_MOVE
liefern Achsendaten zum Eingabestift, d. h. X- und Y-Koordinaten, Druck, Ausrichtung, Neigung und Mausbewegung.
Um den Zugriff auf diese Daten zu ermöglichen, stellt die MotionEvent
API getAxisValue(int)
bereit, wobei der Parameter eine der folgenden Achsenkennungen ist:
Axis | Rückgabewert von getAxisValue() |
---|---|
AXIS_X |
X-Koordinate eines Bewegungsereignisses. |
AXIS_Y |
Y-Koordinate eines Bewegungsereignisses. |
AXIS_PRESSURE |
Bei Touchscreens oder Touchpads wird der Druck durch einen Finger, einen Eingabestift oder einen anderen Zeiger aufgewendet. Bei einer Maus oder einem Trackball: 1, wenn die primäre Taste gedrückt wird, andernfalls 0. |
AXIS_ORIENTATION |
Bei einem Touchscreen oder Touchpad die Ausrichtung eines Fingers, Eingabestifts oder eines anderen Zeigers relativ zur vertikalen Ebene des Geräts. |
AXIS_TILT |
Der Neigungswinkel des Eingabestifts in Radiant. |
AXIS_DISTANCE |
Abstand des Eingabestifts vom 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 handhaben.
Position
Sie können die x- und y-Koordinaten eines Zeigers mit den folgenden Aufrufen abrufen:
MotionEvent#getAxisValue(AXIS_X)
oderMotionEvent#getX()
MotionEvent#getAxisValue(AXIS_Y)
oderMotionEvent#getY()
Luftdruck
Sie können den Zeigerdruck mit den folgenden Aufrufen abrufen:
getAxisValue(AXIS_PRESSURE)
oder getPressure()
für den ersten Mauszeiger.
Der Druckwert für Touchscreens oder Touchpads liegt zwischen 0 (kein Druck) und 1. Je nach Bildschirmkalibrierung können jedoch auch höhere Werte zurückgegeben werden.
Ausrichtung
Die Ausrichtung gibt an, in welche Richtung der Eingabestift zeigt.
Die Ausrichtung des Zeigers kann mithilfe von getAxisValue(AXIS_ORIENTATION)
oder getOrientation()
(für den ersten Zeiger) abgerufen werden.
Bei einem Eingabestift wird die Ausrichtung als Radiantenwert zwischen 0 und pi (Π) im Uhrzeigersinn oder von 0 bis -pi gegen den Uhrzeigersinn zurückgegeben.
Mithilfe der Ausrichtung kannst du einen echten Pinsel implementieren. Wenn der Eingabestift beispielsweise einen flachen Pinsel darstellt, hängt seine Breite von der Ausrichtung des Eingabestifts ab.
Neigen
Die Neigung misst die Neigung des Eingabestifts im Verhältnis zum Bildschirm.
Die Neigung gibt den positiven Winkel des Eingabestifts in Radiant 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 Kurzform für den ersten Zeiger).
Mithilfe der Neigung lassen sich so nah wie möglich reale Werkzeuge reproduzieren, z. B. die Schattierung mit einem geneigten Bleistift.
Hover
Den Abstand des Eingabestifts zum Bildschirm kannst du mit getAxisValue(AXIS_DISTANCE)
abrufen. Die Methode gibt einen Wert von 0, 0 (Kontakt mit dem Bildschirm) und höhere Werte zurück, wenn sich der Eingabestift vom Bildschirm wegbewegt. 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, sollten Sie sich für app-kritische Funktionen nicht auf genaue Werte verlassen.
Mit dem Mauszeiger über den Eingabestift kann eine Vorschau der Größe des Pinsels angezeigt oder angezeigt werden, dass eine Schaltfläche ausgewählt wird.
Hinweis:In der Funktion „Compose“ finden Sie eine Reihe von Modifikatorelementen, mit denen Sie den Status von UI-Elementen ändern können:
hoverable
: Konfigurieren Sie die Komponente so, dass sie sich über Eingabe- und Exit-Ereignisse über den Mauszeiger bewegen kann.indication
: Zeichnet visuelle Effekte für diese Komponente, wenn Interaktionen stattfinden.
Manuelles Ablehnen, Navigation und unerwünschte Eingaben
Manchmal werden bei Multi-Touch-Bildschirmen unerwünschte Berührungen erfasst, z. B. wenn ein Nutzer seine Hand auf dem Bildschirm ablegt, um sich beim Schreiben zu unterstützen. Die Entsperrung per Handzeichen wird erkannt und Sie erhalten eine Benachrichtigung, dass die letzte Einrichtung (MotionEvent
) abgebrochen werden sollte.
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 in einer 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 die vorherige Gruppe von Bewegungsereignissen abgebrochen werden soll.
ACTION_CANCEL
wird ausgelöst, wenn Folgendes erkannt wird:
- Touch-Gesten für die Navigation
- Ablehnung von Handflächen
Wenn ACTION_CANCEL
ausgelöst wird, sollten Sie den aktiven Cursor mit getPointerId(getActionIndex())
identifizieren. Entfernen Sie dann die mit diesem Zeiger erstellte Kontur aus dem Eingabeverlauf und rendern Sie die Szene noch einmal.
FLAG_ABGEBROCHEN
In Android 13 (API-Level 33) hinzugefügt
FLAG_CANCELED
gibt an, dass der Zeiger durch eine unbeabsichtigte Berührung des Nutzers nach oben gegangen ist. Die Markierung wird normalerweise gesetzt, wenn der Nutzer versehentlich den Bildschirm berührt, z. B. indem er das Gerät hält oder die Handfläche auf den Bildschirm legt.
So greifen Sie auf den Flag-Wert zu:
Kotlin
val cancel = (event.flags and FLAG_CANCELED) == FLAG_CANCELED
Java
boolean cancel = (event.getFlags() & FLAG_CANCELED) == FLAG_CANCELED;
Wenn das Flag gesetzt ist, müssen Sie den letzten Satz MotionEvent
ausgehend von der letzten ACTION_DOWN
von diesem Punkt aus rückgängig machen.
Wie bei ACTION_CANCEL
kann der Mauszeiger mit getPointerId(actionIndex)
gefunden werden.
Vollbild, randloses Display und Navigationsgesten
Wenn eine App im Vollbildmodus angezeigt wird und am Rand handlungsrelevante Elemente enthält, wie z. B. der Canvas einer Zeichnungs- oder Notizen-App, kann es zu unerwünschten Berührungen auf dem Canvas kommen, wenn Sie vom unteren Bildschirmrand wischen, um die Navigation anzuzeigen oder die App in den Hintergrund zu verschieben.
Um zu verhindern, dass Gesten unerwünschte Berührungen in Ihrer App auslösen, können Sie Einsätze und ACTION_CANCEL
verwenden.
Weitere Informationen finden Sie oben im Abschnitt Handschriftablehnung, Navigation und unerwünschte Eingaben.
Verwenden Sie die Methode setSystemBarsBehavior()
und BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
von WindowInsetsController
, um zu verhindern, dass Navigationsgesten unerwünschte Touch-Ereignisse verursachen:
Kotlin
// Configure the behavior of the hidden system bars. windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
Java
// Configure the behavior of the hidden system bars. windowInsetsController.setSystemBarsBehavior( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE );
Weitere Informationen zur Einfügung und zum Verwalten von Gesten finden Sie unter:
- Systemleisten für immersiven Modus ausblenden
- Kompatibilität mit Bedienung über Gesten gewährleisten
- Inhalte in Ihrer App randvoll anzeigen
Niedrige Latenz
Die Latenz ist die Zeit, die von der Hardware, dem System und der Anwendung benötigt wird, um Nutzereingaben zu verarbeiten und zu rendern.
Latenz = Hardware- und Betriebssystemeingabeverarbeitung + Anwendungsverarbeitung + Systemzusammensetzung + Hardware-Rendering
Quelle der Latenz
- Registrieren des Eingabestifts mit Touchscreen (Hardware): Erste kabellose Verbindung, wenn der Eingabestift und das Betriebssystem miteinander kommunizieren, um registriert und synchronisiert zu werden.
- Berührungsabtastrate (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): Austausch von Puffern, Hardwareverarbeitung.
Grafiken mit niedriger Latenz
Die Jetpack-Grafikbibliothek mit niedriger Latenz reduziert die Verarbeitungszeit zwischen Nutzereingabe und Bildschirmrendering.
Die Bibliothek reduziert die Verarbeitungszeit, indem sie Multi-buffer-Rendering vermeidet und eine Rendering-Technik für Frontbuffer nutzt, bei der direkt in den Bildschirm geschrieben wird.
Rendering des Frontzwischenspeichers
Der Frontpuffer ist der Arbeitsspeicher, den der Bildschirm für das Rendering verwendet. So können Apps direkt auf dem Bildschirm zeichnen. Dank der niedrigen Latenzbibliothek können Anwendungen direkt im Front-Zwischenspeicher gerendert werden. Dadurch wird die Leistung verbessert, weil der Austausch von Zwischenspeichern verhindert wird, wie es häufig beim Rendering mit mehreren Zwischenspeichern oder beim Rendering mit doppelt Zwischenspeichern der Fall ist.
Frontbuffer-Rendering ist zwar eine großartige Technik, um einen kleinen Bereich des Bildschirms zu rendern, ist jedoch nicht für die Aktualisierung des gesamten Bildschirms gedacht. Beim Rendern des Frontbuffers rendert die App Inhalte in einen Zwischenspeicher, aus dem die Anzeige Daten liest. Dies kann zu Rendering-Artefakten oder zu Reißen 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 Implementierung des Frontbuffer-Renderings bereit. Die Bibliothek wird als Abhängigkeit in die Moduldatei build.gradle
der App eingefügt:
dependencies {
implementation "androidx.graphics:graphics-core:1.0.0-alpha03"
}
GLFrontBufferRenderer-Callbacks
Die Bibliothek mit niedriger Latenz umfasst die GLFrontBufferRenderer.Callback
-Schnittstelle, die die folgenden Methoden definiert:
Die Bibliothek mit niedriger Latenz berücksichtigt nicht den Datentyp, den Sie mit GLFrontBufferRenderer
verwenden.
Die Bibliothek verarbeitet die Daten jedoch als Strom von Hunderten von Datenpunkten. Gestalten Sie Ihre Daten daher so, dass die Speichernutzung und die Speicherzuweisung optimiert werden.
Rückrufe
Implementieren Sie GLFrontBufferedRenderer.Callback
und überschreiben Sie onDrawFrontBufferedLayer()
und onDrawDoubleBufferedLayer()
, um Rendering-Callbacks zu aktivieren. GLFrontBufferedRenderer
verwendet die Callbacks, um deine Daten bestmöglich zu rendern.
Kotlin
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. } }
Java
GLFrontBufferedRenderer.Callback<DATA_TYPE> callbacks = new GLFrontBufferedRenderer.Callback<DATA_TYPE>() { @Override public void onDrawFrontBufferedLayer(@NonNull EGLManager eglManager, @NonNull BufferInfo bufferInfo, @NonNull float[] transform, DATA_TYPE data_type) { // OpenGL for front buffer, short, affecting small area of the screen. } @Override public void onDrawDoubleBufferedLayer(@NonNull EGLManager eglManager, @NonNull BufferInfo bufferInfo, @NonNull float[] transform, @NonNull Collection<? extends DATA_TYPE> collection) { // OpenGL full scene rendering. } };
Instanz von GLFrontBufferedRenderer deklarieren
Bereiten Sie die GLFrontBufferedRenderer
vor, indem Sie die SurfaceView
und die Callbacks angeben, die Sie zuvor erstellt haben. GLFrontBufferedRenderer
optimiert das Rendering im Vordergrund und den doppelten Zwischenspeicher mithilfe deiner Callbacks:
Kotlin
var glFrontBufferRenderer = GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks)
Java
GLFrontBufferedRenderer<DATA_TYPE> glFrontBufferRenderer = new GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks);
Rendering
Das Rendering des Front-Zwischenspeichers beginnt, wenn Sie die renderFrontBufferedLayer()
-Methode aufrufen, die den onDrawFrontBufferedLayer()
-Callback auslöst.
Das doppelte Rendering wird fortgesetzt, wenn Sie die Funktion commit()
aufrufen, die den onDrawMultiDoubleBufferedLayer()
-Callback auslöst.
Im folgenden Beispiel wird der Prozess im vorderen Zwischenspeicher (schnelles Rendering) gerendert, wenn der Nutzer mit dem Zeichnen auf dem Bildschirm beginnt (ACTION_DOWN
) und den Mauszeiger darüber bewegt (ACTION_MOVE
). Der Vorgang wird im doppelten Zwischenspeicher gerendert, wenn der Zeiger die Oberfläche des Bildschirms verlässt (ACTION_UP
).
Mit requestUnbufferedDispatch()
können Sie festlegen, dass das Eingabesystem Bewegungsereignisse nicht im Batch verarbeiten soll, sondern sie stattdessen sendet, sobald sie verfügbar sind:
Kotlin
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() } }
Java
switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: { // Deliver input events as soon as they arrive. surfaceView.requestUnbufferedDispatch(motionEvent); // Pointer is in contact with the screen. glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE); } break; case MotionEvent.ACTION_MOVE: { // Pointer is moving. glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE); } break; case MotionEvent.ACTION_UP: { // Pointer is not in contact in the screen. glFrontBufferRenderer.commit(); } break; case MotionEvent.ACTION_CANCEL: { // Cancel front buffer; remove last motion set from the screen. glFrontBufferRenderer.cancel(); } break; }
Gebote und Verbote beim Rendering
Dos
Kleine Teile des Bildschirms, Handschrift, Zeichnung, Skizzieren.
Nicht erlaubt
Vollbildaktualisierung, Schwenken, Zoomen. Kann zu Tränen führen.
Tränend
Wenn der Bildschirm aktualisiert wird, während der Bildschirmzwischenspeicher gleichzeitig geändert wird, entstehen Tränen. Ein Teil des Bildschirms zeigt neue Daten, ein anderer Teil alte Daten.
Bewegungsvorhersage
Die Jetpack-Bibliothek für Bewegungsvorhersagen reduziert die wahrgenommene Latenz, indem sie den Strichpfad des Nutzers schätzt und temporäre, künstliche Punkte für den Renderer bereitstellt.
Die Bibliothek für Bewegungsvorhersagen erhält echte Nutzereingaben als MotionEvent
-Objekte. Die Objekte enthalten Informationen zu x- und y-Koordinaten, Druck und Zeit, die vom Bewegungsprädiktor genutzt werden, um zukünftige MotionEvent
-Objekte vorherzusagen.
Die vorhergesagten MotionEvent
-Objekte sind nur Schätzungen. Vorhergesagte Ereignisse können die wahrgenommene Latenz reduzieren, aber vorhergesagte Daten müssen durch tatsächliche MotionEvent
-Daten ersetzt werden, sobald sie empfangen wurden.
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.
Abhängigkeiten
Die Bewegungsvorhersagebibliothek ermöglicht die Implementierung der Vorhersage. Die Bibliothek wird als Abhängigkeit in die Moduldatei build.gradle
der App eingefügt:
dependencies {
implementation "androidx.input:input-motionprediction:1.0.0-beta01"
}
Implementierung
Die Bibliothek für Bewegungsvorhersagen enthält die Schnittstelle MotionEventPredictor
, die die folgenden Methoden definiert:
record()
: speichertMotionEvent
-Objekte als Datensatz der Nutzeraktionenpredict()
: gibt einen vorhergesagtenMotionEvent
zurück
Instanz von MotionEventPredictor
deklarieren
Kotlin
var motionEventPredictor = MotionEventPredictor.newInstance(view)
Java
MotionEventPredictor motionEventPredictor = MotionEventPredictor.newInstance(surfaceView);
Daten in den Predictor einspeisen
Kotlin
motionEventPredictor.record(motionEvent)
Java
motionEventPredictor.record(motionEvent);
Vorhersage
Kotlin
when (motionEvent.action) { MotionEvent.ACTION_MOVE -> { val predictedMotionEvent = motionEventPredictor?.predict() if(predictedMotionEvent != null) { // use predicted MotionEvent to inject a new artificial point } } }
Java
switch (motionEvent.getAction()) { case MotionEvent.ACTION_MOVE: { MotionEvent predictedMotionEvent = motionEventPredictor.predict(); if(predictedMotionEvent != null) { // use predicted MotionEvent to inject a new artificial point } } break; }
Tipps zur Bewegungsvorhersage
Dos
Vorhersagepunkte werden entfernt, wenn ein neuer vorhergesagter Punkt hinzugefügt wird.
Nicht erlaubt
Verwenden Sie für das endgültige Rendering keine Vorhersagepunkte.
Notizen-Apps
Mit ChromeOS kann deine App bestimmte Aktionen zum Erstellen von Notizen deklarieren.
Informationen zum Registrieren einer App als Notizen-App unter ChromeOS finden Sie unter Eingabekompatibilität.
Weitere Informationen zum Registrieren einer App als Notizen-App auf Android-Geräten finden Sie unter Notizen-App erstellen.
Mit Android 14 (API-Level 34) wurde der Intent ACTION_CREATE_NOTE
eingeführt, mit dem deine App eine Notizaktivität auf dem Sperrbildschirm starten kann.
Digitale Tintenerkennung mit ML Kit
Mit der digitalen Tintenerkennung von ML Kit kann Ihre App handschriftlichen Text auf einer digitalen Oberfläche in Hunderten von Sprachen 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 auch Touch-Gesten erkennen, z. B. Löschen und Einkreisen.
Weitere Informationen finden Sie unter Digitale Tintenerkennung.