Panduan - Menggunakan Touch di Android
Mari kita lihat cara menggunakan konsep dari bagian sebelumnya dalam aplikasi yang berfungsi. Kami akan membuat aplikasi dengan empat aktivitas. Aktivitas pertama akan menjadi menu atau switchboard yang akan meluncurkan aktivitas lain untuk menunjukkan berbagai API. Cuplikan layar berikut menunjukkan aktivitas utama:
Aktivitas pertama, Sampel Sentuh, akan menunjukkan cara menggunakan penanganan aktivitas untuk menyentuh Tampilan. Aktivitas Gesture Recognizer akan menunjukkan cara subkelas Android.View.Views
dan menangani peristiwa serta menunjukkan cara menangani gerakan mencubit. Aktivitas ketiga dan terakhir, Custom Gesture, akan menunjukkan cara menggunakan gerakan kustom. Untuk mempermudah diikuti dan diserap, kita akan memecah panduan ini menjadi beberapa bagian, dengan setiap bagian berfokus pada salah satu Aktivitas.
Aktivitas Sampel Sentuhan
Buka TouchWalkthrough_Start proyek. MainActivity diatur untuk pergi - terserah kami untuk menerapkan perilaku sentuhan dalam aktivitas. Jika Anda menjalankan aplikasi dan mengklik Sampel Sentuh, aktivitas berikut harus dimulai:
Sekarang setelah kami mengonfirmasi bahwa Aktivitas dimulai, buka file TouchActivity.cs dan tambahkan handler untuk
Touch
peristiwaImageView
:_touchMeImageView.Touch += TouchMeImageViewOnTouch;
Selanjutnya, tambahkan metode berikut ke TouchActivity.cs:
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; }
Perhatikan dalam kode di atas bahwa kami memperlakukan Move
dan Down
bertindak sebagai sama. Ini karena meskipun pengguna mungkin tidak mengangkat jari mereka dari ImageView
, itu dapat bergerak atau tekanan yang dikeluarkan oleh pengguna dapat berubah. Jenis perubahan ini akan menghasilkan Move
tindakan.
Setiap kali pengguna menyentuh ImageView
, Touch
acara akan dinaikkan dan handler kami akan menampilkan pesan Touch Begins di layar, seperti yang ditunjukkan pada cuplikan layar berikut:
Selama pengguna menyentuh ImageView
, Touch Begins akan ditampilkan di TextView
. Ketika pengguna tidak lagi menyentuh ImageView
, pesan Touch Ends akan ditampilkan di TextView
, seperti yang ditunjukkan pada cuplikan layar berikut:
Aktivitas Pengenalan Gerakan
Sekarang mari kita terapkan aktivitas Gesture Recognizer. Aktivitas ini akan menunjukkan cara menyeret tampilan di sekitar layar dan mengilustrasikan salah satu cara untuk mengimplementasikan pinch-to-zoom.
Tambahkan Aktivitas baru ke aplikasi yang disebut
GestureRecognizer
. Edit kode untuk aktivitas ini sehingga menyerupan kode berikut:public class GestureRecognizerActivity : Activity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); View v = new GestureRecognizerView(this); SetContentView(v); } }
Tambahkan tampilan Android baru ke proyek, dan beri nama
GestureRecognizerView
. Tambahkan variabel berikut ke kelas ini: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;
Tambahkan konstruktor berikut ke
GestureRecognizerView
. Konstruktor ini akan menambahkanImageView
aktivitas kami. Pada titik ini kode masih tidak akan dikompilasi - kita perlu membuat kelasMyScaleListener
yang akan membantu mengubah ukuranImageView
ketika pengguna mencubitnya: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)); }
Untuk menggambar gambar pada aktivitas kami, kita perlu mengambil alih
OnDraw
metode kelas Tampilan seperti yang ditunjukkan dalam cuplikan berikut. Kode ini akan memindahkanImageView
ke posisi yang ditentukan oleh_posX
dan_posY
serta mengubah ukuran gambar sesuai dengan faktor penskalakan:protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); canvas.Save(); canvas.Translate(_posX, _posY); canvas.Scale(_scaleFactor, _scaleFactor); _icon.Draw(canvas); canvas.Restore(); }
Selanjutnya kita perlu memperbarui variabel
_scaleFactor
instansImageView
saat pengguna mencubit . Kami akan menambahkan kelas yang disebutMyScaleListener
. Kelas ini akan mendengarkan peristiwa skala yang akan dinaikkan oleh Android ketika pengguna mencubitImageView
. Tambahkan kelas dalam berikut keGestureRecognizerView
. Kelas ini adalahScaleGesture.SimpleOnScaleGestureListener
. Kelas ini adalah kelas kenyamanan yang dapat di-subkelas pendengar ketika Anda tertarik dengan subset gerakan: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; } }
Metode berikutnya yang perlu kita ambil alih
GestureRecognizerView
adalahOnTouchEvent
. Kode berikut mencantumkan implementasi lengkap metode ini. Ada banyak kode di sini, jadi mari kita mengambil satu menit dan melihat apa yang terjadi di sini. Hal pertama yang dilakukan metode ini adalah menskalakan ikon jika perlu - ini ditangani dengan memanggil_scaleDetector.OnTouchEvent
. Selanjutnya kita mencoba mencari tahu tindakan apa yang disebut metode ini:Jika pengguna menyentuh layar dengan, kami merekam posisi X dan Y dan ID pointer pertama yang menyentuh layar.
Jika pengguna memindahkan sentuhan mereka di layar, maka kami mencari tahu seberapa jauh pengguna memindahkan pointer.
Jika pengguna telah mengangkat jarinya dari layar, maka kita akan berhenti melacak gerakan.
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; }
Sekarang jalankan aplikasi, dan mulai aktivitas Gesture Recognizer. Ketika memulai layar akan terlihat seperti cuplikan layar di bawah ini:
Sekarang sentuh ikon, dan seret di sekitar layar. Coba gerakan pinch-to-zoom. Pada titik tertentu layar Anda mungkin terlihat seperti cuplikan layar berikut:
Pada titik ini Anda harus memberi diri Anda tepuk di bagian belakang: Anda baru saja mengimplementasikan pinch-to-zoom dalam aplikasi Android! Istirahat sejenak dan mari kita lanjutkan ke Aktivitas ketiga dan terakhir dalam panduan ini - menggunakan gerakan kustom.
Aktivitas Gerakan Kustom
Layar akhir dalam panduan ini akan menggunakan gerakan kustom.
Untuk tujuan Panduan ini, pustaka gerakan telah dibuat menggunakan Gesture Tool dan ditambahkan ke proyek dalam file Sumber Daya/mentah/gerakan. Dengan sedikit pembersihan rumah tangga ini keluar dari jalan, mari kita mulai dengan Aktivitas akhir di panduan.
Tambahkan file tata letak bernama custom_gesture_layout.axml ke proyek dengan konten berikut. Proyek sudah memiliki semua gambar di folder Sumber Daya :
<?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>
Selanjutnya tambahkan Aktivitas baru ke proyek dan beri nama
CustomGestureRecognizerActivity.cs
. Tambahkan dua variabel instans ke kelas , seperti yang ditunjukkan dalam dua baris kode berikut:private GestureLibrary _gestureLibrary; private ImageView _imageView;
OnCreate
Edit metode Aktivitas ini sehingga menyerupan kode berikut. Mari kita luangkan waktu satu menit untuk menjelaskan apa yang terjadi dalam kode ini. Hal pertama yang kita lakukan adalah membuat instansGestureOverlayView
dan mengaturnya sebagai tampilan akar Aktivitas. Kami juga menetapkan penanganan aktivitas keGesturePerformed
peristiwaGestureOverlayView
. Selanjutnya kita mengembang file tata letak yang dibuat sebelumnya, dan menambahkannya sebagai tampilan anak dariGestureOverlayView
. Langkah terakhir adalah menginisialisasi variabel_gestureLibrary
dan memuat file gerakan dari sumber daya aplikasi. Jika file gerakan tidak dapat dimuat karena alasan tertentu, tidak banyak yang dapat dilakukan Aktivitas ini, sehingga dimatikan: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(); } }
Hal terakhir yang perlu kita lakukan untuk mengimplementasikan metode
GestureOverlayViewOnGesturePerformed
seperti yang ditunjukkan dalam cuplikan kode berikut.GestureOverlayView
Ketika mendeteksi gerakan, ia memanggil kembali ke metode ini. Hal pertama yang kita coba dapatkan objekIList<Prediction>
yang cocok dengan gerakan dengan memanggil_gestureLibrary.Recognize()
. Kami menggunakan sedikit LINQ untuk mendapatkanPrediction
yang memiliki skor tertinggi untuk gerakan.Jika tidak ada gerakan yang cocok dengan skor yang cukup tinggi, maka penanganan aktivitas keluar tanpa melakukan apa pun. Jika tidak, kami memeriksa nama prediksi dan mengubah gambar yang ditampilkan berdasarkan nama gerakan:
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); } }
Jalankan aplikasi dan mulai aktivitas Custom Gesture Recognizer. Ini akan terlihat seperti cuplikan layar berikut:
Sekarang gambar tanda centang di layar, dan bitmap yang ditampilkan akan terlihat seperti yang ditunjukkan pada cuplikan layar berikutnya:
Terakhir, gambar coretan di layar. Kotak centang harus berubah kembali ke gambar aslinya seperti yang ditunjukkan pada cuplikan layar ini:
Anda sekarang memiliki pemahaman tentang cara mengintegrasikan sentuhan dan gerakan dalam aplikasi Android menggunakan Xamarin.Android.