Bu derste, temas etkinliklerindeki hareketlerin nasıl izleneceği açıklanmaktadır.
Dokunmatik kişinin konumu, basıncı veya boyutu değiştiğinde bir ACTION_MOVE
etkinliğiyle yeni bir onTouchEvent()
tetiklenir. Genel hareketleri algılama bölümünde açıklandığı gibi, tüm bu etkinlikler onTouchEvent()
öğesinin MotionEvent
parametresine kaydedilir.
Parmakla dokunma her zaman en hassas etkileşim biçimi olmadığından, dokunma etkinliklerinin algılanması basit temastan ziyade genellikle harekete dayanır. Android, harekete dayalı hareketleri (ör. kaydırma) hareketsiz hareketleri (ör. tek bir dokunma) ayırt etmesine yardımcı olmak için dokunma kayması kavramını içerir. Dokunma eğimi, hareket, harekete dayalı bir hareket olarak yorumlanmadan önce kullanıcının dokunuşunun gezinebileceği piksel cinsinden mesafeyi ifade eder. Bu konu hakkında daha fazla bilgi için ViewGroup'ta dokunma etkinliklerini yönetme bölümüne bakın.
Uygulamanızın ihtiyaçlarına bağlı olarak, bir hareketle hareketi izlemenin birkaç yolu vardır. Aşağıda örnekler verilmiştir:
- İşaretçinin başlangıç ve bitiş konumu. Örneğin, ekrandaki bir nesneyi A noktasından B noktasına hareket ettirir.
- İşaretçinin ilerlediği yön (X ve Y koordinatlarıyla belirlenir).
- Geçmiş'e dokunun. Bir hareket geçmişinin boyutunu
MotionEvent
yönteminigetHistorySize()
çağırarak bulabilirsiniz. Daha sonra, hareket etkinliğiningetHistorical<Value>
yöntemlerini kullanarak geçmiş etkinliklerin her birinin konumlarını, boyutlarını, zamanlarını ve basınçlarını elde edebilirsiniz. Geçmişe kayıt, kullanıcının parmağının izini oluştururken (dokunmatik çizimde olduğu gibi) yararlı olur. Ayrıntılar içinMotionEvent
referansına bakın. - İşaretçinin dokunmatik ekran boyunca hareket ettiği hız.
Aşağıdaki ilgili kaynakları inceleyin:
Hızı takip edin
İşaretçinin hareket ettiği mesafeye veya yöne dayalı, harekete dayalı bir hareket oluşturabilirsiniz. Bununla birlikte, hız genellikle bir hareketin özelliklerini izlemede veya hareketin gerçekleşip gerçekleşmediğine karar vermede belirleyici bir faktördür. Android, hız hesaplamasını kolaylaştırmak için VelocityTracker
sınıfını sunar.
VelocityTracker
, dokunma etkinliklerinin hızını takip etmenize yardımcı olur. Bu, hızın hareket ölçütlerinin bir parçası olduğu hareketler (ör. hızla sallama) için yararlıdır.
VelocityTracker
API'deki yöntemlerin amacını gösteren bir örneği aşağıda bulabilirsiniz:
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 yakalama özelliğini kullanma
Oyunlar, uzaktan masaüstü ve sanallaştırma istemcileri gibi bazı uygulamalar, fare işaretçisi üzerinde kontrol sahibi olma avantajından faydalanır. İşaretçi yakalama, Android 8.0 (API düzeyi 26) ve sonraki sürümlerde kullanılabilen bir özelliktir. Bu özellik, tüm fare etkinliklerini uygulamanızda odaklanmış görünüme sunarak bu denetimi sağlar.
İşaretçi yakalama isteğinde bulunma
Uygulamanızdaki bir görünüm, yalnızca söz konusu görünümü içeren görünüm hiyerarşisine odaklanıldığında işaretçi yakalama isteğinde bulunabilir. Bu nedenle, görünümde belirli bir kullanıcı işlemi olduğunda (ör. bir onClick()
etkinliği veya etkinliğinizin onWindowFocusChanged()
etkinlik işleyicisinde olduğu gibi) işaretçi yakalama isteğinde bulunun.
İşaretçi yakalama isteğinde bulunmak için görünümde requestPointerCapture()
yöntemini çağırın. Aşağıdaki kod örneğinde, kullanıcı bir görünümü tıkladığında işaretçi yakalamanın nasıl isteneceği gösterilmektedir:
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)
yöntemini çağırır.
Sistem, yakalamayı isteyen görünümle aynı görünüm hiyerarşisinde olduğu sürece fare etkinliklerini uygulamanızdaki odaklanmış görünüme yayınlar. Diğer uygulamalar, yakalama yayınlanana kadar ACTION_OUTSIDE
etkinlikleri gibi fare etkinliklerini almaz. Android, fare dışındaki kaynaklardan gelen işaretçi etkinliklerini normal gibi yayınlar, ancak fare işaretçisi artık görünmez.
Yakalanan işaretçi etkinliklerini işleme
Bir görünüm işaretçi yakalamayı başarılı bir şekilde edindikten sonra, Android fare etkinliklerini yayınlar. Odaklanılan görünümünüz, aşağıdaki görevlerden birini gerçekleştirerek etkinlikleri işleyebilir:
- Özel görünüm kullanıyorsanız
onCapturedPointerEvent(MotionEvent)
değerini geçersiz kılın. - Aksi halde
OnCapturedPointerListener
kaydettirin.
Aşağıdaki kod örneğinde onCapturedPointerEvent(MotionEvent)
özelliğinin nasıl uygulanacağı gösterilmektedir:
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
'in nasıl kaydedileceği gösterilmektedir:
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 dinleyiciyi kaydedin, görünümünüz, bir iztopu cihazının ilettiği koordinatlara benzer şekilde X veya Y delta gibi göreli hareketleri belirten işaretçi koordinatlarına sahip bir MotionEvent
alır. Koordinatları almak için getX()
ve getY()
tuşlarını kullanabilirsiniz.
İşaretçi yakalamayı bırakın
Aşağıdaki kod örneğinde gösterildiği gibi, uygulamanızdaki görünüm releasePointerCapture()
yöntemini çağırarak işaretçi yakalamayı serbest bırakabilir:
Kotlin
override fun onClick(view: View) { view.releasePointerCapture() }
Java
@Override public void onClick(View view) { view.releasePointerCapture(); }
Sistem, siz açıkça releasePointerCapture()
çağrısı yapmadan yakalamayı görünümden kaldırabilir. Bunun nedeni genellikle, isteklerin yakaladığı görünümü içeren görünüm hiyerarşisinin odağı kaybetmesidir.