Android uygulamalarında farklı jest’leri tanımamız gerekebiliyor. Bunlardan en temeli savurma jesti (fling gesture) diyebiliriz.. Bu yazımda savurma jestini nasıl yakalayabileceğimizden bahsedeceğim.

Olayları kullanarak geliştireceğimiz bu uygulamadan önce mutlaka özeleştirilmiş olay yönetimi yazımı okumanızı tavsiye ederim. Konu ile alkalı kodlar burada açıklanmayacaktır.

Öncelikle istediğimiz activity’de kullanabileceğimiz bir jest dinleyici hazırlamakla başlayacağız. Bu aslında Android SDK ile beraber gelen OnTouchListener arayüzünü implement edecek soyut (abstract) bir sınıf olacak.

1- Savurma olayı ile ilgili kod parçaları

a- Savurma olayı dinleyici arayüz

import java.util.EventListener;

public interface FlingEventListener extends EventListener {
  public void onFlingEventOccurred(FlingEvent event);
}

b- Savurma yönü tanımlamak için enumeratör.

public enum FlingDirection {
  LeftToRight,
  RightToLeft,
  TopToBottom,
  BottomToTop
}

c- Savurma olay sınıfı

import java.util.EventObject;

/**
 * Özelleştirilmiş olay sınıfı.
 */
public class FlingEvent extends EventObject {
  private FlingDirection flingDirection;

  public FlingEvent(Object source, FlingDirection flingDirection) {
    super(source);
    setFlingDirection(flingDirection);
  }

  public FlingDirection getFlingDirection() {
    return flingDirection;
  }

  private void setFlingDirection(FlingDirection flingDirection) {
    this.flingDirection = flingDirection;
  }
}

2- Savurma tanıma

import java.util.ArrayList;
import java.util.List;

import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

/**
 * Her view için kullanabileceğimiz bir savurma jest'i dinleyici hazırlıyoruz.
 */
public class FlingDetector implements OnTouchListener {
  private final GestureDetector gestureDetector = new GestureDetector(new FlingGestureListener());
  private List listeners = new ArrayList();

  public synchronized void addEventListener(FlingEventListener listener) {
    listeners.add(listener);
  }

  public synchronized void removeEventListener(FlingEventListener listener) {
    listeners.remove(listener);
  }

  /**
   * Dokunma olayında herhangi bir savurma gerçekleşip gerçekleşmediğini algılayacağız.
   */
  public boolean onTouch(final View v, final MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
  }

  private synchronized void fireEvent(final FlingDirection flingDirection) {
    FlingEvent event = new FlingEvent(this, flingDirection);
    for (FlingEventListener listener : listeners) {
      listener.onFlingEventOccurred(event);
    }
  }

  /**
   * Savurma olayını yakalayan ve ne yöne gerçekleştiğini tanıyan sınıfımız.
   */
  private final class FlingGestureListener extends SimpleOnGestureListener {
    private static final int swipeMinDistance = 60;
    private static final int swipeThresholdVelocity = 100;
    private static final int swipeMinTime = 250;

    public FlingGestureListener() {
      super();
    }

    /**
     * onDown (Basma) olayı doğru (true) döndürdüğü sürece bir olay tanınabilir. Bu önemli.
     */
    @Override
    public boolean onDown(final MotionEvent e) {
      return e.getDownTime() > swipeMinTime;
    }

    /**
     * Savurma olayının gerçekleşmesini tanıyan ve gerekli olayı fırlatan metot.
     */
    @Override
    public boolean onFling(final MotionEvent e1, final MotionEvent e2,
        final float velocityX, final float velocityY) {
      if (e1.getX() - e2.getX() > swipeMinDistance
          && Math.abs(velocityX) > swipeThresholdVelocity) {
        fireEvent(FlingDirection.RightToLeft);
      } else if (e2.getX() - e1.getX() > swipeMinDistance
          && Math.abs(velocityX) > swipeThresholdVelocity) {
        fireEvent(FlingDirection.LeftToRight);
      } else if (e1.getY() - e2.getY() > swipeMinDistance
          && Math.abs(velocityY) > swipeThresholdVelocity) {
        fireEvent(FlingDirection.BottomToTop);
      } else if (e2.getY() - e1.getY() > swipeMinDistance
          && Math.abs(velocityY) > swipeThresholdVelocity) {
        fireEvent(FlingDirection.TopToBottom);
      } else {
        return false;
      }

      return true;
    }
  }
}

3- Uygulama içinde kullanımı

/**
 * Sınıfımız olayı yakalamak için mutlaka FlingEventListener arayüzünü implement etmeli.
 */
public class AndroidTestActivity extends Activity implements FlingEventListener {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);

    // Savurma olayını dinlemek istediğimizi bildiriyoruz.
    final FlingDetector flingDetector = new FlingDetector();
    flingDetector.addEventListener(this);

    // Savrulma olayı yakalanmak isteyen view objeleri burada eklenmeli.
    mainLayout.setOnTouchListener(flingDetector);
  }

  public void onFlingEventOccurred(FlingEvent event) {
    final TextView textViewEvent = (TextView) findViewById(R.id.textViewEvent);

    switch (event.getFlingDirection()) {
    case LeftToRight:
      textViewEvent.setText("Left to Right");
      break;
    case RightToLeft:
      textViewEvent.setText("Right to Left");
      break;
    case TopToBottom:
      textViewEvent.setText("Top to Bottom");
      break;
    case BottomToTop:
      textViewEvent.setText("Bottom to Top");
      break;
    default:
      throw new UnsupportedOperationException("Unsupported fling direction.");
    }
  }
}

Sonuç olarak aşağıda görebileceğiniz gibi çalışan bir jest tanıma gerçekleştirmiş olduk.

Image

Bu makalemde jest tanımayı olay mantığı ile nasıl yapacağımızı görmüş olduk. Biraz uzun olduğunu biliyorum. Eğer açık olmadığını düşündüğünüz bir yer varsa bunu yorum ile bana bildirirseniz memnun olurum. Başka bir yazımda görüşmek üzere..