Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Sehen wir uns an, wie die Konzepte aus dem vorherigen Abschnitt in einer funktionierenden Anwendung verwendet werden. Wir erstellen eine Anwendung mit vier Aktivitäten. Die erste Aktivität ist ein Menü oder eine Übersicht, die die anderen Aktivitäten startet, um die verschiedenen APIs zu veranschaulichen. Der folgende Screenshot zeigt die Standard Aktivität:
Im ersten Aktivitätsbeispiel wird gezeigt, wie Ereignishandler zum Berühren der Ansichten verwendet werden. Die Gestenerkennungsaktivität veranschaulicht, wie Sie Unterklassen Android.View.Views und Ereignisse behandeln und wie Gesten behandelt werden. Die dritte und letzte Aktivität, benutzerdefinierte Geste, zeigt, wie benutzerdefinierte Gesten verwendet werden. Um Dies zu vereinfachen und zu absorbieren, werden wir diese exemplarische Vorgehensweise in Abschnitte unterteilen, wobei sich jeder Abschnitt auf einen der Aktivitäten konzentriert.
Touch-Beispielaktivität
Öffnen Sie das Projekt TouchWalkthrough_Start. Die MainActivity ist alles im Griff – es liegt an uns, das Touchverhalten in der Aktivität umzusetzen. Wenn Sie die Anwendung ausführen und auf "Touchbeispiel" klicken, sollte die folgende Aktivität gestartet werden:
Nachdem wir nun bestätigt haben, dass die Aktivität gestartet wird, öffnen Sie die Datei TouchActivity.cs , und fügen Sie einen Handler für das
TouchEreignis derImageView:_touchMeImageView.Touch += TouchMeImageViewOnTouch;Fügen Sie als Nächstes die folgende Methode zum TouchActivity.cs hinzu:
private void TouchMeImageViewOnTouch(object sender, View.TouchEventArgs touchEventArgs) { string message; switch (touchEventArgs.Event.Action & MotionEventActions.Mask) { case MotionEventActions.Down: case MotionEventActions.Move: message = "Touch Begins"; break; case MotionEventActions.Up: message = "Touch Ends"; break; default: message = string.Empty; break; } _touchInfoTextView.Text = message; }
Beachten Sie im obigen Code, dass wir die und Down die Move Aktion genauso behandeln. Dies liegt daran, dass sich der Benutzer, auch wenn er den Finger nicht vom Finger hebt ImageView, sich bewegen kann oder der vom Benutzer ausgeübte Druck geändert werden kann. Diese Arten von Änderungen generieren eine Move Aktion.
Jedes Mal, wenn der Benutzer das ImageViewEreignis berührt, wird das Touch Ereignis ausgelöst, und unser Handler zeigt die Meldung "Touch Begins " auf dem Bildschirm an, wie im folgenden Screenshot gezeigt:
Solange der Benutzer die ImageViewFingereingabe berührt, wird "Touch Begins " im TextViewBereich angezeigt. Wenn der Benutzer die ImageViewFingereingabe nicht mehr berührt, wird die Meldung "Touch Ends " im TextViewfolgenden Screenshot angezeigt:
Gestikerkennungsaktivität
Ermöglicht jetzt die Implementierung der Gestenerkennungsaktivität. Diese Aktivität veranschaulicht, wie Sie eine Ansicht um den Bildschirm ziehen und eine Möglichkeit zum Implementieren des Zusammendrückens zum Zoomen veranschaulichen.
Fügen Sie der Anwendung eine neue Aktivität hinzu, die aufgerufen wird
GestureRecognizer. Bearbeiten Sie den Code für diese Aktivität so, dass er dem folgenden Code ähnelt:public class GestureRecognizerActivity : Activity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); View v = new GestureRecognizerView(this); SetContentView(v); } }Fügen Sie dem Projekt eine neue Android-Ansicht hinzu, und nennen Sie sie
GestureRecognizerView. Fügen Sie dieser Klasse die folgenden Variablen hinzu:private static readonly int InvalidPointerId = -1; private readonly Drawable _icon; private readonly ScaleGestureDetector _scaleDetector; private int _activePointerId = InvalidPointerId; private float _lastTouchX; private float _lastTouchY; private float _posX; private float _posY; private float _scaleFactor = 1.0f;Fügen Sie den folgenden Konstruktor zu
GestureRecognizerView. Dieser Konstruktor fügt unserer Aktivität einenImageViewhinzu. An diesem Punkt wird der Code immer noch nicht kompiliert – wir müssen die KlasseMyScaleListenererstellen, die beim Zusammendrücken derImageViewGröße des Benutzers hilft:public GestureRecognizerView(Context context): base(context, null, 0) { _icon = context.Resources.GetDrawable(Resource.Drawable.Icon); _icon.SetBounds(0, 0, _icon.IntrinsicWidth, _icon.IntrinsicHeight); _scaleDetector = new ScaleGestureDetector(context, new MyScaleListener(this)); }Um das Bild für unsere Aktivität zu zeichnen, müssen wir die
OnDrawMethode der View-Klasse außer Kraft setzen, wie im folgenden Codeausschnitt gezeigt. Dieser Code verschebt dieImageViewposition, die durch_posXund_posYändert die Größe des Bilds entsprechend dem Skalierungsfaktor:protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); canvas.Save(); canvas.Translate(_posX, _posY); canvas.Scale(_scaleFactor, _scaleFactor); _icon.Draw(canvas); canvas.Restore(); }Als Nächstes müssen wir die Instanzvariable
_scaleFactoraktualisieren, während der Benutzer dieImageView. Wir fügen eine Klasse mit dem NamenMyScaleListenerhinzu. Diese Klasse lauscht auf die Skalierungsereignisse, die von Android ausgelöst werden, wenn der Benutzer dieImageView. Fügen Sie die folgende innere Klasse zuGestureRecognizerView. Diese Klasse ist einScaleGesture.SimpleOnScaleGestureListener. Diese Klasse ist eine Komfortklasse, die Listener unterklassen können, wenn Sie an einer Teilmenge von Gesten interessiert sind:private class MyScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener { private readonly GestureRecognizerView _view; public MyScaleListener(GestureRecognizerView view) { _view = view; } public override bool OnScale(ScaleGestureDetector detector) { _view._scaleFactor *= detector.ScaleFactor; // put a limit on how small or big the image can get. if (_view._scaleFactor > 5.0f) { _view._scaleFactor = 5.0f; } if (_view._scaleFactor < 0.1f) { _view._scaleFactor = 0.1f; } _view.Invalidate(); return true; } }Die nächste Methode, in
GestureRecognizerViewder wir außer Kraft setzen müssen, istOnTouchEvent. Der folgende Code listet die vollständige Implementierung dieser Methode auf. Hier gibt es viel Code, also lassen Sie sich eine Minute dauern und sehen, was hier passiert. Als Erstes skaliert diese Methode das Symbol bei Bedarf – dies wird durch Aufrufen_scaleDetector.OnTouchEventbehandelt. Als Nächstes versuchen wir herauszufinden, welche Aktion diese Methode aufgerufen hat:Wenn der Benutzer den Bildschirm berührt hat, zeichnen wir die X- und Y-Position und die ID des ersten Zeigers auf, der den Bildschirm berührt hat.
Wenn der Benutzer seine Toucheingabe auf dem Bildschirm bewegt hat, stellen wir fest, wie weit der Benutzer den Zeiger bewegt hat.
Wenn der Benutzer seinen Finger vom Bildschirm entfernt hat, beenden wir die Nachverfolgung der Gesten.
public override bool OnTouchEvent(MotionEvent ev) { _scaleDetector.OnTouchEvent(ev); MotionEventActions action = ev.Action & MotionEventActions.Mask; int pointerIndex; switch (action) { case MotionEventActions.Down: _lastTouchX = ev.GetX(); _lastTouchY = ev.GetY(); _activePointerId = ev.GetPointerId(0); break; case MotionEventActions.Move: pointerIndex = ev.FindPointerIndex(_activePointerId); float x = ev.GetX(pointerIndex); float y = ev.GetY(pointerIndex); if (!_scaleDetector.IsInProgress) { // Only move the ScaleGestureDetector isn't already processing a gesture. float deltaX = x - _lastTouchX; float deltaY = y - _lastTouchY; _posX += deltaX; _posY += deltaY; Invalidate(); } _lastTouchX = x; _lastTouchY = y; break; case MotionEventActions.Up: case MotionEventActions.Cancel: // We no longer need to keep track of the active pointer. _activePointerId = InvalidPointerId; break; case MotionEventActions.PointerUp: // check to make sure that the pointer that went up is for the gesture we're tracking. pointerIndex = (int) (ev.Action & MotionEventActions.PointerIndexMask) >> (int) MotionEventActions.PointerIndexShift; int pointerId = ev.GetPointerId(pointerIndex); if (pointerId == _activePointerId) { // This was our active pointer going up. Choose a new // action pointer and adjust accordingly int newPointerIndex = pointerIndex == 0 ? 1 : 0; _lastTouchX = ev.GetX(newPointerIndex); _lastTouchY = ev.GetY(newPointerIndex); _activePointerId = ev.GetPointerId(newPointerIndex); } break; } return true; }Führen Sie nun die Anwendung aus, und starten Sie die Gestenerkennungsaktivität. Wenn der Bildschirm gestartet wird, sollte etwa wie der folgende Screenshot aussehen:
Tippen Sie nun auf das Symbol, und ziehen Sie es um den Bildschirm. Probieren Sie die Zusammendrücken-zu-Zoom-Geste aus. Irgendwann sieht der Bildschirm ungefähr wie der folgende Screenshot aus:
An dieser Stelle sollten Sie sich einen Paten auf den Rücken geben: Sie haben gerade Zusammendrücken in einer Android-Anwendung implementiert! Machen Sie eine kurze Pause und können sie in dieser exemplarischen Vorgehensweise mit benutzerdefinierten Gesten zur dritten und endgültigen Aktivität wechseln.
Benutzerdefinierte Gestenaktivität
Der letzte Bildschirm in dieser exemplarischen Vorgehensweise verwendet benutzerdefinierte Gesten.
Für diese exemplarische Vorgehensweise wurde die Gestenbibliothek bereits mithilfe des Gestiktools erstellt und dem Projekt in den Dateiressourcen /Roh-/Gesten hinzugefügt. Mit diesem Stück Haushaltung aus dem Weg können Sie mit der endgültigen Aktivität in der exemplarischen Vorgehensweise loswerden.
Fügen Sie dem Projekt eine Layoutdatei mit dem Namen custom_gesture_layout.axml mit dem folgenden Inhalt hinzu. Das Projekt verfügt bereits über alle Bilder im Ordner "Ressourcen ":
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <ImageView android:src="@drawable/check_me" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:id="@+id/imageView1" android:layout_gravity="center_vertical" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>Fügen Sie dem Projekt als Nächstes eine neue Aktivität hinzu, und nennen Sie sie
CustomGestureRecognizerActivity.cs. Fügen Sie der Klasse zwei Instanzenvariablen hinzu, wie in den folgenden beiden Codezeilen dargestellt:private GestureLibrary _gestureLibrary; private ImageView _imageView;Bearbeiten Sie die
OnCreateMethode dieser Aktivität so, dass sie dem folgenden Code ähnelt. Lassen Sie uns eine Minute dauern, um zu erläutern, was in diesem Code passiert. Als Erstes instanziieren wir eineGestureOverlayViewInstanziierung und legen sie als Stammansicht der Aktivität fest. Außerdem weisen wir demGesturePerformedEreignis einesGestureOverlayViewEreignisses einen Ereignishandler zu. Als Nächstes wird die zuvor erstellte Layoutdatei aufgeblasen und als untergeordnete Ansicht derGestureOverlayViewDatei hinzugefügt. Der letzte Schritt besteht darin, die Variable_gestureLibraryzu initialisieren und die Gestendatei aus den Anwendungsressourcen zu laden. Wenn die Gestendatei aus irgendeinem Grund nicht geladen werden kann, gibt es nicht viel dieser Aktivität, sodass sie heruntergefahren wird:protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); GestureOverlayView gestureOverlayView = new GestureOverlayView(this); SetContentView(gestureOverlayView); gestureOverlayView.GesturePerformed += GestureOverlayViewOnGesturePerformed; View view = LayoutInflater.Inflate(Resource.Layout.custom_gesture_layout, null); _imageView = view.FindViewById<ImageView>(Resource.Id.imageView1); gestureOverlayView.AddView(view); _gestureLibrary = GestureLibraries.FromRawResource(this, Resource.Raw.gestures); if (!_gestureLibrary.Load()) { Log.Wtf(GetType().FullName, "There was a problem loading the gesture library."); Finish(); } }Abschließend müssen wir die Methode
GestureOverlayViewOnGesturePerformedimplementieren, wie im folgenden Codeausschnitt gezeigt. Wenn dieGestureOverlayViewGeste erkannt wird, ruft sie diese Methode zurück. Als Erstes versuchen wir, objekteIList<Prediction>abzurufen, die mit der Geste übereinstimmen, indem wir aufrufen_gestureLibrary.Recognize(). Wir verwenden ein bisschen LINQ, um diePredictionhöchste Punktzahl für die Geste zu erhalten.Wenn keine Übereinstimmungsgeste mit einer hohen Punktzahl vorhanden ist, wird der Ereignishandler beendet, ohne etwas zu tun. Andernfalls überprüfen wir den Namen der Vorhersage und ändern das angezeigte Bild basierend auf dem Namen der Geste:
private void GestureOverlayViewOnGesturePerformed(object sender, GestureOverlayView.GesturePerformedEventArgs gesturePerformedEventArgs) { IEnumerable<Prediction> predictions = from p in _gestureLibrary.Recognize(gesturePerformedEventArgs.Gesture) orderby p.Score descending where p.Score > 1.0 select p; Prediction prediction = predictions.FirstOrDefault(); if (prediction == null) { Log.Debug(GetType().FullName, "Nothing seemed to match the user's gesture, so don't do anything."); return; } Log.Debug(GetType().FullName, "Using the prediction named {0} with a score of {1}.", prediction.Name, prediction.Score); if (prediction.Name.StartsWith("checkmark")) { _imageView.SetImageResource(Resource.Drawable.checked_me); } else if (prediction.Name.StartsWith("erase", StringComparison.OrdinalIgnoreCase)) { // Match one of our "erase" gestures _imageView.SetImageResource(Resource.Drawable.check_me); } }Führen Sie die Anwendung aus, und starten Sie die Aktivität "Benutzerdefinierte Gestenerkennung". Es sollte ungefähr wie der folgende Screenshot aussehen:
Zeichnen Sie nun ein Häkchen auf dem Bildschirm, und die angezeigte Bitmap sollte ungefähr wie in den nächsten Screenshots dargestellt aussehen:
Zeichnen Sie schließlich einen Skizzenausschnitt auf dem Bildschirm. Das Kontrollkästchen sollte wie in den folgenden Screenshots dargestellt wieder in das ursprüngliche Bild geändert werden:
Sie wissen jetzt, wie Sie Toucheingaben und Gesten in eine Android-Anwendung mit Xamarin.Android integrieren.







