Dokunma ve işaretçi hareketlerini izleme

"Oluştur" yöntemini deneyin
Jetpack Compose, Android için önerilen kullanıcı arayüzü araç setidir. Oluşturma'da dokunma ve giriş özelliklerini nasıl kullanacağınızı öğrenin.
Hareketler → 'nı inceleyin.

Bu derste, dokunma etkinliklerinde hareketin nasıl izleneceği açıklanmaktadır.

Yeni bir onTouchEvent() bir ACTION_MOVE etkinlik mevcut dokunma temas konumu, basınç veya boyut değiştiğinde. Farklı Genel hareketleri algılama konusunda açıklandığı gibi bu etkinlikler MotionEvent parametresi onTouchEvent().

Parmakla dokunmak her zaman en hassas etkileşim biçimi değildir. Dokunma olaylarının tespit edilmesi, basit temastan çok harekete dayalı olarak belirlenir. Uygulamaların, harekete dayalı hareketler (ör. kaydırma) ile hareketleri birbirinden ayırt etmesine yardımcı olmak için hareket içermeyen hareketler (tek bir dokunma gibi), Android'de dokunma eğimi. Dokunma eğimi, kullanıcının dokunabileceği mesafeyi piksel cinsinden belirtir harekete dayalı bir hareket olarak yorumlanmasından önce etrafta dolaşmanızı sağlar. Daha fazla daha fazla bilgi için Dokunmatik etkinlikleri ViewGroup.

Bir hareketteki hareketi izlemenin çeşitli yolları vardır: ve en iyi uygulamaları paylaşacağız. Aşağıda bazı örnekler verilmiştir:

  • İşaretçinin başlangıç ve bitiş konumu (ör. ekrandaki bir öğeyi hareket ettirme) bir nesnedir.
  • İşaretçinin hareket ettiği yön (X ve Y ile belirlenir) koordinatlar.
  • Geçmiş'e dokunun. Bir hareketin geçmişinin boyutunu, MotionEvent yöntem getHistorySize() Ardından bu öğelerin her birinin konumunu, boyutlarını, süresini ve basınçlarını hareket etkinliğinin getHistorical<Value>. yöntemlerine göz atın. Geçmişe kayıt özelliği, kullanıcının parmağıyla ilgili bir izin (örneğin, gibi sorular sorabilirsiniz. Ayrıntılar için MotionEvent referansına bakın.
  • İşaretçinin dokunmatik ekranda hareket ederken hızı.

Aşağıdaki ilgili kaynaklara bakın:

Hız izleme

Mesafeye veya yöne dayalı harekete dayalı bir hareketiniz olabilir işaretçi hareket ettirilir. Ancak, hız genellikle izleme sürecinde belirleyici bir faktördür bir hareketin özelliklerini veya hareketin gerçekleşip gerçekleşmediğine karar verebilirsiniz. Şunun için: hız hesaplamasını kolaylaştıran Android, VelocityTracker sınıfı. VelocityTracker, dokunma etkinliklerinin hızını izlemenize yardımcı olur. Faydalı Örneğin, hızın harekete ilişkin ölçütlerin bir parçası olduğu hareketler için bir kaçamak.

Burada, VelocityTracker API'si:

Kotlin

private const val DEBUG_TAG = "Velocity"

class MainActivity : Activity() {
    private var mVelocityTracker: VelocityTracker? = null

    override fun onTouchEvent(event: MotionEvent): Boolean {

        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                // Reset the velocity tracker back to its initial state.
                mVelocityTracker?.clear()
                // If necessary, retrieve a new VelocityTracker object to watch
                // the velocity of a motion.
                mVelocityTracker = mVelocityTracker ?: VelocityTracker.obtain()
                // Add a user's movement to the tracker.
                mVelocityTracker?.addMovement(event)
            }
            MotionEvent.ACTION_MOVE -> {
                mVelocityTracker?.apply {
                    val pointerId: Int = event.getPointerId(event.actionIndex)
                    addMovement(event)
                    // When you want to determine the velocity, call
                    // computeCurrentVelocity(). Then, call getXVelocity() and
                    // getYVelocity() to retrieve the velocity for each pointer
                    // ID.
                    computeCurrentVelocity(1000)
                    // Log velocity of pixels per second. It's best practice to
                    // use VelocityTrackerCompat where possible.
                    Log.d("", "X velocity: ${getXVelocity(pointerId)}")
                    Log.d("", "Y velocity: ${getYVelocity(pointerId)}")
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                // Return a VelocityTracker object back to be re-used by others.
                mVelocityTracker?.recycle()
                mVelocityTracker = null
            }
        }
        return true
    }
}

Java

public class MainActivity extends Activity {
    private static final String DEBUG_TAG = "Velocity";
        ...
    private VelocityTracker mVelocityTracker = null;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int index = event.getActionIndex();
        int action = event.getActionMasked();
        int pointerId = event.getPointerId(index);

        switch(action) {
            case MotionEvent.ACTION_DOWN:
                if(mVelocityTracker == null) {
                    // Retrieve a new VelocityTracker object to watch the
                    // velocity of a motion.
                    mVelocityTracker = VelocityTracker.obtain();
                }
                else {
                    // Reset the velocity tracker back to its initial state.
                    mVelocityTracker.clear();
                }
                // Add a user's movement to the tracker.
                mVelocityTracker.addMovement(event);
                break;
            case MotionEvent.ACTION_MOVE:
                mVelocityTracker.addMovement(event);
                // When you want to determine the velocity, call
                // computeCurrentVelocity(). Then call getXVelocity() and
                // getYVelocity() to retrieve the velocity for each pointer ID.
                mVelocityTracker.computeCurrentVelocity(1000);
                // Log velocity of pixels per second. It's best practice to use
                // VelocityTrackerCompat where possible.
                Log.d("", "X velocity: " + mVelocityTracker.getXVelocity(pointerId));
                Log.d("", "Y velocity: " + mVelocityTracker.getYVelocity(pointerId));
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // Return a VelocityTracker object back to be re-used by others.
                mVelocityTracker.recycle();
                break;
        }
        return true;
    }
}

İşaretçi yakalamayı kullan

Oyunlar, uzaktan masaüstü ve sanallaştırma istemcileri gibi bazı uygulamalar kontrol sahibi olmanızı engeller. İşaretçi yakalama, kullanıcıların Bu kontrolü sağlayan ve Android 8.0 (API düzeyi 26) ve sonraki sürümlerde kullanılabilir. Böylece, tüm fare etkinliklerini uygulamanızda odaklanmış bir görünüme gönderebilirsiniz.

İşaretçi yakalama isteğinde bulun

Uygulamanızdaki bir görünüm, yalnızca içerir. Bu nedenle, bir istek olduğunda işaretçi yakalamayı belirli bir kullanıcı işlemi (örneğin, onClick() veya onWindowFocusChanged() yardımcı olur.

İşaretçi yakalama isteğinde bulunmak için requestPointerCapture() yöntemini kullanabilirsiniz. Aşağıdaki kod örneğinde işaretçinin nasıl isteneceği gösterilmektedir Kullanıcı bir görünümü tıkladığında yakalanır:

Kotlin

fun onClick(view: View) {
    view.requestPointerCapture()
}

Java

@Override
public void onClick(View view) {
    view.requestPointerCapture();
}

İşaretçiyi yakalama isteği başarılı olduğunda Android, onPointerCaptureChange(true). Sistem, aşağıdaki koşullar karşılandığı sürece fare etkinliklerini uygulamanızdaki odaklı görünüme sunar. yakalamayı isteyen görünümle aynı görünüm hiyerarşisindedir. Diğer Aşağıdakiler dahil olmak üzere, yakalama yayınlanana kadar fare etkinlikleri almayı durdurur. ACTION_OUTSIDE etkinlikler. Android, fare dışındaki kaynaklardan işaretçi etkinliklerini normal, ancak fare işaretçisi artık görünmüyor.

Yakalanan işaretçi etkinliklerini işleme

Görünüm işaretçi yakalamayı başarıyla aldıktan sonra, Android için de geçerlidir. Odaklanmış görünümünüz şu işlemlerden birini gerçekleştirerek etkinlikleri işleyebilir: şu görevlerden yararlanabilirsiniz:

Aşağıdaki kod örneğinde, onCapturedPointerEvent(MotionEvent):

Kotlin

override fun onCapturedPointerEvent(motionEvent: MotionEvent): Boolean {
    // Get the coordinates required by your app.
    val verticalOffset: Float = motionEvent.y
    // Use the coordinates to update your view and return true if the event is
    // successfully processed.
    return true
}

Java

@Override
public boolean onCapturedPointerEvent(MotionEvent motionEvent) {
  // Get the coordinates required by your app.
  float verticalOffset = motionEvent.getY();
  // Use the coordinates to update your view and return true if the event is
  // successfully processed.
  return true;
}

Aşağıdaki kod örneğinde, OnCapturedPointerListener:

Kotlin

myView.setOnCapturedPointerListener { view, motionEvent ->
    // Get the coordinates required by your app.
    val horizontalOffset: Float = motionEvent.x
    // Use the coordinates to update your view and return true if the event is
    // successfully processed.
    true
}

Java

myView.setOnCapturedPointerListener(new View.OnCapturedPointerListener() {
  @Override
  public boolean onCapturedPointer (View view, MotionEvent motionEvent) {
    // Get the coordinates required by your app.
    float horizontalOffset = motionEvent.getX();
    // Use the coordinates to update your view and return true if the event is
    // successfully processed.
    return true;
  }
});

İster özel bir görünüm kullanın ister bir işleyiciyi kaydedin, görünümünüz X gibi göreli hareketleri belirten işaretçi koordinatlarına sahip MotionEvent koordinatlara benzer şekilde, iztopu cihazı tarafından iletilen koordinatlara benzer. Şunları yapabilirsiniz: koordinat almak için getX() ve getY().

İşaretçi yakalamayı bırakın

Uygulamanızdaki görünüm, şunu çağırarak işaretçi yakalamayı serbest bırakabilir: releasePointerCapture() aşağıdaki kod örneğinde gösterildiği gibidir:

Kotlin

override fun onClick(view: View) {
    view.releasePointerCapture()
}

Java

@Override
public void onClick(View view) {
    view.releasePointerCapture();
}

Sistem, siz açıkça belirtmeden yakalamayı görünümden kaldırabilir releasePointerCapture() çağrılıyor, genellikle görünüm hiyerarşisi yakalama isteğinde bulunan görünümün odağı kaybolduğu anlamına gelir.