Das Zeichnen einer Benutzeroberfläche ist nur ein Teil der Erstellung einer benutzerdefinierten Ansicht. Außerdem müssen Sie Ihre Ansicht so auf Nutzereingaben reagieren, die dem die Sie imitieren.
Die Objekte in Ihrer App sollten sich wie echte Objekte verhalten. Lassen Sie beispielsweise dass Bilder in Ihrer App nicht mehr existieren und an anderer Stelle wieder angezeigt werden, da Objekte in der Praxis nicht tun. Verschieben Sie Ihre Bilder stattdessen an einen anderen Ort eine andere.
Die Nutzenden spüren selbst subtiles Verhalten oder Gefühl in einer Benutzeroberfläche und reagieren am besten auf Feinheiten, die die reale Welt nachahmen. Wenn Nutzende beispielsweise ein UI-Objekt verwenden, um ihnen am Anfang ein Gefühl der Trägheit zu vermitteln, die die Bewegung verzögert. Am Ende geben Sie ihnen einen Impuls, der das Objekt über das schleudern.
Auf dieser Seite wird gezeigt, wie Sie mithilfe der Funktionen des Android-Frameworks um diese realen Verhaltensweisen in Ihre benutzerdefinierte Ansicht einzubinden.
Weitere verwandte Informationen finden Sie unter Eingabeereignisse und Eigenschaftsanimation Übersicht.
Touch-Gesten zur Eingabe
Wie viele andere UI-Frameworks unterstützt Android ein Eingabeereignismodell. Nutzer
zu Ereignissen, die Rückrufe auslösen, und Sie können den Wert
können Sie anpassen,
wie Ihre App auf den Nutzer reagiert. Die gängigste Eingabe
ist touch im Android-System, das den
onTouchEvent(android.view.MotionEvent)
Überschreiben Sie diese Methode, um das Ereignis so zu verarbeiten:
Kotlin
override fun onTouchEvent(event: MotionEvent): Boolean { return super.onTouchEvent(event) }
Java
@Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }
Berührungsereignisse an sich sind nicht besonders nützlich. Moderne Touch-Benutzeroberflächen
Interaktionen in Bezug auf Gesten wie Tippen, Ziehen, Drücken
oder Zoomen. Um unbearbeitete Touch-Ereignisse in Gesten umzuwandeln,
bietet
GestureDetector
Erstellen Sie ein GestureDetector
, indem Sie eine Instanz einer Klasse übergeben.
die das
GestureDetector.OnGestureListener
.
Wenn Sie nur wenige Gesten verarbeiten möchten, können Sie
GestureDetector.SimpleOnGestureListener
anstatt die GestureDetector.OnGestureListener
zu implementieren,
. Mit diesem Code wird beispielsweise eine Klasse erstellt,
GestureDetector.SimpleOnGestureListener
und Überschreibungen
onDown(MotionEvent)
.
Kotlin
private val myListener = object : GestureDetector.SimpleOnGestureListener() { override fun onDown(e: MotionEvent): Boolean { return true } } private val detector: GestureDetector = GestureDetector(context, myListener)
Java
class MyListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return true; } } detector = new GestureDetector(getContext(), new MyListener());
Unabhängig davon, ob Sie GestureDetector.SimpleOnGestureListener
verwenden oder nicht,
sollten Sie immer eine
onDown()
, die true
zurückgibt. Dies ist notwendig, da alle Touch-Gesten
mit einer onDown()
-Nachricht beginnen. Wenn Sie false
zurückgeben
von onDown()
, als
GestureDetector.SimpleOnGestureListener
tut, geht das System davon aus,
den Rest der Geste und die anderen Methoden der
GestureDetector.OnGestureListener
werden nicht angerufen. Nur Rückgabe
false
von onDown()
, wenn du einen ganzen Text ignorieren möchtest
Touch-Geste.
Nachdem Sie GestureDetector.OnGestureListener
implementiert und erstellt haben
eine Instanz von GestureDetector
enthält, können Sie Ihren
GestureDetector
, um die Touch-Ereignisse zu interpretieren, die Sie in
onTouchEvent()
Kotlin
override fun onTouchEvent(event: MotionEvent): Boolean { return detector.onTouchEvent(event).let { result -> if (!result) { if (event.action == MotionEvent.ACTION_UP) { stopScrolling() true } else false } else true } }
Java
@Override public boolean onTouchEvent(MotionEvent event) { boolean result = detector.onTouchEvent(event); if (!result) { if (event.getAction() == MotionEvent.ACTION_UP) { stopScrolling(); result = true; } } return result; }
Wenn du onTouchEvent()
ein nicht übergebenes Touch-Ereignis übergibst
als Teil einer Geste erkennen, wird false
zurückgegeben. Sie können dann
Ihren eigenen Code für die Bewegungserkennung verwenden.
Physisch plausible Bewegungen erzeugen
Gesten sind eine wirkungsvolle Methode, Geräte mit Touchscreen zu steuern, unlogisch und schwer einprägsam, es sei denn, sie produzieren physisch plausibles Ergebnis.
Angenommen, Sie möchten eine horizontale Fling-Geste implementieren, legt das gezeichnete Element in der Ansicht fest, die sich um seine vertikale Achse dreht. Diese Geste wenn die Benutzeroberfläche reagiert, indem sie sich schnell in Richtung des und verlangsamt dann, als ob der Nutzer auf ein Schwungrad drückt und es dreht.
Die Dokumentation zum
Scrollen animieren
Touch-Geste liefert eine detaillierte Erklärung, wie du deinen eigenen Scoll implementieren kannst
verhalten. Den Eindruck eines Schwungrads zu simulieren, ist jedoch nicht ganz einfach. Die Physik ist viel
und mathematische Berechnungen notwendig sind, damit ein Schwungradmodell richtig funktioniert. Glücklicherweise
Android bietet Hilfsklassen, mit denen dieses und andere Verhaltensweisen simuliert werden können. Die
Scroller
ist die Grundlage für die Handhabung von Flieg-Gesten im Flywheel-Stil.
Um einen Fling zu starten, ruf
fling()
durch die Startgeschwindigkeit und den Mindest- und Höchstwert x und y
die Werte des Fling. Für den Geschwindigkeitswert können Sie den Wert verwenden, der von
GestureDetector
Kotlin
fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { scroller.fling( currentX, currentY, (velocityX / SCALE).toInt(), (velocityY / SCALE).toInt(), minX, minY, maxX, maxY ) postInvalidate() return true }
Java
@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { scroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY); postInvalidate(); return true; }
Durch den Aufruf von fling()
wird das Physikmodell für den Fling eingerichtet.
Touch-Geste. Anschließend aktualisieren Sie die Scroller
durch folgenden Aufruf:
Scroller.computeScrollOffset()
in regelmäßigen Abständen. computeScrollOffset()
aktualisiert die
Interner Status des Scroller
-Objekts durch Lesen der aktuellen Zeit und
mit dem physikalischen Modell die x- und y-Position an dieser Stelle
. Anruf
getCurrX()
und
getCurrY()
um diese Werte abzurufen.
Bei den meisten Ansichten passieren x und y des Scroller
-Objekts.
direkt zu den
scrollTo()
.
Dieses Beispiel ist etwas anders: Hier wird die aktuelle Scroll-x-Position verwendet.
um den Drehwinkel der Ansicht festzulegen.
Kotlin
scroller.apply { if (!isFinished) { computeScrollOffset() setItemRotation(currX) } }
Java
if (!scroller.isFinished()) { scroller.computeScrollOffset(); setItemRotation(scroller.getCurrX()); }
Die Klasse Scroller
berechnet Scrollpositionen für Sie,
werden diese Positionen nicht automatisch auf Ihre Ansicht angewendet. Neue Koordinaten anwenden
damit die Scroll-Animation flüssig wirkt. Es gibt zwei Möglichkeiten,
Gehen Sie wie folgt vor:
- Erzwingen einer Neuzeichnung durch den Aufruf
postInvalidate()
nach dem Aufruf vonfling()
. Bei dieser Technik müssen Sie Scroll-Offsets berechnen,onDraw()
und rufen Sie jedes MalpostInvalidate()
auf, wenn der Scroll-Offset Änderungen. - Richten Sie ein
ValueAnimator
, um für die Dauer des Flinges zu animieren und einen Listener hinzuzufügen, mit dem Aufruf vonaddUpdateListener()
. Mit diesem Verfahren können Sie die EigenschaftenView
Reibungslose Übergänge
Die Nutzenden erwarten, dass eine moderne Benutzeroberfläche reibungslos zwischen den Status wechselt: UI-Elemente das Ein- und Ausblenden statt Erscheinen und Verschwinden und Bewegungen beginnen statt abrupt zu starten und anzuhalten. Das Android- Eigenschaftsanimation Framework für reibungslose Übergänge.
Wenn Sie das Animationssystem verwenden, wird jedes Mal, wenn eine Eigenschaft die Auswirkungen auf Ihre
Darstellung der Ansicht ändern möchten, ändern Sie die Eigenschaft nicht direkt. Verwenden Sie stattdessen
ValueAnimator
, um die Änderung vorzunehmen. Im folgenden Beispiel
Wenn Sie die ausgewählte untergeordnete Komponente in der Ansicht ändern,
wird das gesamte gerenderte Element
so drehen, dass der Auswahlzeiger zentriert ist.
ValueAnimator
ändert die Rotation über einen Zeitraum von mehreren Hundert.
Millisekunden, anstatt den neuen Rotationswert sofort festzulegen.
Kotlin
autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0).apply { setIntValues(targetAngle) duration = AUTOCENTER_ANIM_DURATION start() }
Java
autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0); autoCenterAnimator.setIntValues(targetAngle); autoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION); autoCenterAnimator.start();
Wenn der Wert, den Sie ändern möchten, einer der Basis-View
ist
ist die Animation noch einfacher, da Ansichten eine integrierte
ViewPropertyAnimator
das für die gleichzeitige Animation mehrerer Eigenschaften optimiert ist, wie in der
folgendes Beispiel:
Kotlin
animate() .rotation(targetAngle) .duration = ANIM_DURATION .start()
Java
animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();