İzlenecek yol - Android'de Touch'ı kullanma
Çalışan bir uygulamanın önceki bölümünde yer alan kavramların nasıl kullanılacağını görelim. Dört etkinliği olan bir uygulama oluşturacağız. İlk etkinlik, çeşitli API'leri göstermek için diğer etkinlikleri başlatan bir menü veya geçiş panosu olacaktır. Aşağıdaki ekran görüntüsünde ana etkinlik gösterilmektedir:
İlk Etkinlik olan Dokunma Örneği, Görünümler'e dokunmak için olay işleyicilerinin nasıl kullanılacağını gösterir. Hareket Tanıma etkinliği, olayları alt sınıflama Android.View.Views
ve işlemenin yanı sıra sıkıştırma hareketlerinin nasıl işleneceğini gösterir. Üçüncü ve son etkinlik olan Özel Hareket, özel hareketlerin nasıl kullanıldığını gösterir. İşlerin daha kolay izlenip emilmesini sağlamak için, bu kılavuzu bölümlere ayıracağız ve her bölüm Etkinlikler'in birine odaklanacak.
Dokunma Örneği Etkinliği
Proje TouchWalkthrough_Start açın. MainActivity her şeyi yapmaya hazır – etkinlikte dokunma davranışını uygulamak bize bağlı. Uygulamayı çalıştırıp Dokunma Örneği'ne tıklarsanız aşağıdaki etkinliğin başlatılması gerekir:
Etkinliğin başlatıldığını onayladığımıza göre, TouchActivity.cs dosyasını açın ve olayı
ImageView
içinTouch
bir işleyici ekleyin:_touchMeImageView.Touch += TouchMeImageViewOnTouch;
Ardından, TouchActivity.cs aşağıdaki yöntemi ekleyin:
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; }
Yukarıdaki kodda ve Down
eylemini Move
aynı şekilde ele aldığımıza dikkat edin. Bunun nedeni, kullanıcının parmağından kaldıramasa ImageView
da hareket edebilir veya kullanıcı tarafından uygulanan baskı değişebilir. Bu tür değişiklikler bir Move
eylem oluşturur.
Kullanıcı öğesine her dokunduğunda ImageView
olay tetiklenir ve işleyicimiz, aşağıdaki ekran görüntüsünde gösterildiği gibi Dokunma Başlar iletisini ekranda görüntüler:Touch
Kullanıcı öğesine dokunduğu ImageView
sürece, Dokunma Başlar içinde TextView
görüntülenir. Kullanıcı artık öğesine dokunmadığındaImageView
, aşağıdaki ekran görüntüsünde TextView
gösterildiği gibi Dokunma Uçları iletisi içinde görüntülenir:
Hareket Tanıma Etkinliği
Şimdi Hareket Tanıma etkinliğini uygulayalım. Bu etkinlik, ekranın çevresinde bir görünümün nasıl sürükleneceğini ve sıkıştırma-yakınlaştırmanın tek bir yolunun nasıl gösterileceğini gösterir.
Uygulamaya adlı
GestureRecognizer
yeni bir Etkinlik ekleyin. Bu etkinliğin kodunu, aşağıdaki koda benzeyecek şekilde düzenleyin:public class GestureRecognizerActivity : Activity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); View v = new GestureRecognizerView(this); SetContentView(v); } }
Projeye yeni bir Android görünümü ekleyin ve olarak adlandırın
GestureRecognizerView
. Bu sınıfa aşağıdaki değişkenleri ekleyin: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;
aşağıdaki oluşturucuyu öğesine
GestureRecognizerView
ekleyin. Bu oluşturucu etkinliğimize birImageView
ekler. Bu noktada kod yine derlenmez; kullanıcı sıkıştırdığında yeniden boyutlandırmayaImageView
yardımcı olacak sınıfıMyScaleListener
oluşturmamız gerekir: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)); }
Resmi etkinliğimize çizmek için aşağıdaki kod parçacığında gösterildiği gibi View sınıfının yöntemini geçersiz kılmamız
OnDraw
gerekir. Bu kod,ImageView
öğesini tarafından_posX
belirtilen konuma taşır ve_posY
ölçeklendirme faktörüne göre görüntüyü yeniden boyutlandıracaktır:protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); canvas.Save(); canvas.Translate(_posX, _posY); canvas.Scale(_scaleFactor, _scaleFactor); _icon.Draw(canvas); canvas.Restore(); }
Daha sonra kullanıcı sıkıştırması ile örnek değişkenini
_scaleFactor
ImageView
güncelleştirmemiz gerekir. adlıMyScaleListener
bir sınıf ekleyeceğiz. Bu sınıf, kullanıcı tarafından sıkıştırıldığında Android tarafından tetiklenecek ölçek olaylarınıImageView
dinler. Aşağıdaki iç sınıfı öğesineGestureRecognizerView
ekleyin. Bu sınıf birScaleGesture.SimpleOnScaleGestureListener
. Bu sınıf, hareketlerin bir alt kümesiyle ilgilendiğinizde dinleyicilerin alt sınıf oluşturabileceği bir kolaylık sınıfıdır: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; } }
içinde geçersiz kılmamız
GestureRecognizerView
gereken bir sonraki yöntem:OnTouchEvent
. Aşağıdaki kod, bu yöntemin tam uygulamasını listeler. Burada çok fazla kod var, bu nedenle bir dakikanızı alıp burada neler olduğuna bakalım. Bu yöntemin yaptığı ilk şey gerekirse simgeyi ölçeklendirmektir; bu, çağrılarak_scaleDetector.OnTouchEvent
işlenir. Daha sonra bu yöntemi çağıran eylemi bulmaya çalışacağız:Kullanıcı ekrana ile dokunduysa, X ve Y konumlarını ve ekrana dokunan ilk işaretçinin kimliğini kaydederiz.
Kullanıcı ekranda dokunuşunu taşıdıysa, kullanıcının işaretçiyi ne kadar hareket ettirdiğini anlarız.
Kullanıcı parmağını ekrandan kaldırdıysa hareketleri izlemeyi durdururuz.
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; }
Şimdi uygulamayı çalıştırın ve Hareket Tanıma etkinliğini başlatın. Ekran başlatıldığında aşağıdaki ekran görüntüsüne benzer olmalıdır:
Şimdi simgeye dokunun ve ekranın çevresinde sürükleyin. Sıkıştırma-yakınlaştırma hareketini deneyin. Bir noktada ekranınız aşağıdaki ekran görüntüsüne benzer olabilir:
Bu noktada kendinize sırt üstü bir pat vermelisiniz: Bir Android uygulamasında sıkıştırma-yakınlaştırmayı yeni uyguladınız! Hızlı bir mola verin ve özel hareketleri kullanarak bu kılavuzda üçüncü ve son Etkinliğe geçelim.
Özel Hareket Etkinliği
Bu kılavuzdaki son ekranda özel hareketler kullanılır.
Bu İzlenecek Yol'un amaçları doğrultusunda hareket kitaplığı, Hareket Aracı kullanılarak zaten oluşturulmuş ve Kaynaklar/ham/hareketler dosyasında projeye eklenmiştir. Bu temizlik parçasının aradan çıkmasıyla, izlenecek yoldaki son Etkinlik'e geçelim.
Projeye aşağıdaki içeriklerle custom_gesture_layout.axml adlı bir düzen dosyası ekleyin. Projenin kaynaklar klasöründeki tüm görüntüler zaten var:
<?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>
Ardından projeye yeni bir Etkinlik ekleyin ve adını verin
CustomGestureRecognizerActivity.cs
. Aşağıdaki iki kod satırı içinde gösterildiği gibi sınıfına iki örnek değişkeni ekleyin:private GestureLibrary _gestureLibrary; private ImageView _imageView;
OnCreate
Bu Etkinliğin yöntemini aşağıdaki koda benzeyecek şekilde düzenleyin. Bu kodda neler olduğunu açıklamak için bir dakikanızı alalım. İlk olarak birGestureOverlayView
örneği oluşturup bunu Etkinliğin kök görünümü olarak ayarlayacağız. Ayrıca olayınaGesturePerformed
bir olay işleyicisiGestureOverlayView
atarız. Ardından daha önce oluşturulan düzen dosyasını şişirir ve bunu öğesininGestureOverlayView
alt görünümü olarak ekleriz. Son adım, değişkeni_gestureLibrary
başlatmak ve uygulama kaynaklarından hareketler dosyasını yüklemektir. Hareketler dosyası bir nedenden dolayı yüklenemiyorsa, bu Etkinliğin gerçekleştirebileceği pek bir şey yoktur, bu nedenle kapatılır: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(); } }
Aşağıdaki kod parçacığında gösterildiği gibi yöntemini
GestureOverlayViewOnGesturePerformed
uygulamamız gereken son şey.GestureOverlayView
bir hareket algıladığında, bu yönteme geri çağırır. çağrısı yaparak_gestureLibrary.Recognize()
hareketle eşleşen birIList<Prediction>
nesne almaya çalışacağımız ilk şey. Hareket için en yüksek puana sahip olanı almakPrediction
için biraz LINQ kullanırız.Yeterli puana sahip eşleşen bir hareket yoksa olay işleyicisi hiçbir şey yapmadan çıkar. Aksi takdirde, tahminin adını denetler ve görüntülenen görüntüyü hareketin adına göre değiştiririz:
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); } }
Uygulamayı çalıştırın ve Özel Hareket Tanıma etkinliğini başlatın. Aşağıdaki ekran görüntüsüne benzer olmalıdır:
Şimdi ekrana bir onay işareti çizin ve görüntülenen bit eşlem sonraki ekran görüntülerinde gösterilene benzer olmalıdır:
Son olarak, ekrana bir karalama çizin. Onay kutusu, şu ekran görüntülerinde gösterildiği gibi özgün görüntüsüne geri dönmelidir:
Artık Xamarin.Android kullanarak bir Android uygulamasında dokunma ve hareketleri tümleştirme hakkında bilgi sahibisiniz.