Benutzerdefinierte Ansicht interaktiv gestalten

Schreiben Sie jetzt
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Hier erfahren Sie, wie Sie in „Compose“ mit Layouts arbeiten.
<ph type="x-smartling-placeholder"></ph> Touch-Gesten →

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;
}
<ph type="x-smartling-placeholder">

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 von fling(). Bei dieser Technik müssen Sie Scroll-Offsets berechnen, onDraw() und rufen Sie jedes Mal postInvalidate() 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 von addUpdateListener(). Mit diesem Verfahren können Sie die Eigenschaften View

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();