Bagikan melalui


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:

Contoh cuplikan layar dengan tombol Sentuh Saya

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:

    Cuplikan layar aktivitas dengan Touch Begins ditampilkan

  • Sekarang setelah kami mengonfirmasi bahwa Aktivitas dimulai, buka file TouchActivity.cs dan tambahkan handler untuk Touch peristiwa ImageView:

    _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:

Cuplikan layar aktivitas dengan Touch Begins

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:

Cuplikan layar aktivitas dengan Touch Ends

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 menambahkan ImageView aktivitas kami. Pada titik ini kode masih tidak akan dikompilasi - kita perlu membuat kelas MyScaleListener yang akan membantu mengubah ukuran ImageView 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 memindahkan ImageView 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 instans ImageViewsaat pengguna mencubit . Kami akan menambahkan kelas yang disebut MyScaleListener. Kelas ini akan mendengarkan peristiwa skala yang akan dinaikkan oleh Android ketika pengguna mencubit ImageView. Tambahkan kelas dalam berikut ke GestureRecognizerView. Kelas ini adalah ScaleGesture.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 adalah OnTouchEvent. 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:

    Layar mulai Gesture Recognizer dengan ikon Android

  • Sekarang sentuh ikon, dan seret di sekitar layar. Coba gerakan pinch-to-zoom. Pada titik tertentu layar Anda mungkin terlihat seperti cuplikan layar berikut:

    Ikon gerakan berpindah di sekitar layar

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 instans GestureOverlayView dan mengaturnya sebagai tampilan akar Aktivitas. Kami juga menetapkan penanganan aktivitas ke GesturePerformed peristiwa GestureOverlayView. Selanjutnya kita mengembang file tata letak yang dibuat sebelumnya, dan menambahkannya sebagai tampilan anak dari GestureOverlayView. 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 objek IList<Prediction> yang cocok dengan gerakan dengan memanggil _gestureLibrary.Recognize(). Kami menggunakan sedikit LINQ untuk mendapatkan Prediction 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:

    Cuplikan layar dengan gambar Periksa Saya

    Sekarang gambar tanda centang di layar, dan bitmap yang ditampilkan akan terlihat seperti yang ditunjukkan pada cuplikan layar berikutnya:

    Tanda centang yang digambar, tanda centang dikenali

    Terakhir, gambar coretan di layar. Kotak centang harus berubah kembali ke gambar aslinya seperti yang ditunjukkan pada cuplikan layar ini:

    Coretan pada layar, gambar asli ditampilkan

Anda sekarang memiliki pemahaman tentang cara mengintegrasikan sentuhan dan gerakan dalam aplikasi Android menggunakan Xamarin.Android.