Izgara düzeninde fırlatma hareketi algılama


1105

Almak istediğim flingbenim Android uygulamasında jest algılama çalışma.

Ne var GridLayout9 ImageViews içeren bir . Kaynak burada bulunabilir: Romain Guys'ın Izgara Düzeni .

Aldığım bu dosya Romain Guy'ın Photostream uygulamasından ve sadece biraz uyarlanmış.

Basit tıklama durumu onClickListeneriçin sadece ImageVieweklediğim her biri için activityuygulayan ana olarak ayarlamanız gerekir View.OnClickListener. Bir şeyi tanıyan bir şeyi uygulamak son derece daha karmaşık görünüyor fling. Sanırım bunun nedeni olabilir viewsmi?

  • Etkinliğim uygularsa , bunu eklediğim görünümler veya OnGestureListenerhareket dinleyicisi olarak nasıl ayarlayacağımı bilmiyorum .GridImage

    public class SelectFilterActivity extends Activity implements
       View.OnClickListener, OnGestureListener { ...
  • Eğer aktivitem uygularsa, OnTouchListenero zaman hiçbir onFlingyöntemim yok override(parametrelerin iki olayı var, fırlatmanın kayda değer olup olmadığını belirlememe izin veriyor).

    public class SelectFilterActivity extends Activity implements
        View.OnClickListener, OnTouchListener { ...
  • Bir gelenek yaparsam View, GestureImageViewbu şekilde uzarsa ImageView, bir flinggörünümün gerçekleştiğini nasıl anlatacağımı bilmiyorum . Her durumda, bunu denedim ve ekrana dokunduğumda yöntemler çağrılmadı.

Gerçekten sadece bu görüşler arasında çalışan somut bir örneğe ihtiyacım var. Bunu ne, ne zaman ve nasıl eklemeliyim listener? Tek tıklamaları da tespit edebilmem gerekiyor.

// Gesture detection
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {

    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        int dx = (int) (e2.getX() - e1.getX());
        // don't accept the fling if it's too short
        // as it may conflict with a button push
        if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.absvelocityY)) {
            if (velocityX > 0) {
                moveRight();
            } else {
                moveLeft();
            }
            return true;
        } else {
            return false;
        }
    }
});

Flings yakalamak için ekranımın üstüne şeffaf bir görünüm koymak mümkün mü?

inflateXML'den alt resim görünümlerime seçmezsem , GestureDetectoroluşturucu parametresini oluşturduğum yeni bir alt sınıfa geçirebilir ImageViewmiyim?

Bu flingalgılama için çalışmak için almaya çalışıyorum çok basit bir etkinliktir : SelectFilterActivity (Fotoğraf akışından uyarlanmış) .

Bu kaynaklara bakıyordum:

Şimdiye kadar hiçbir şey benim için işe yaramadı ve bazı işaretçiler umuyordum.


Bu problem nasıl çözülür? Lütfen stackoverflow.com/questions/60464912/…
Bishwash

Yanıtlar:


818

Kodumu durumuma uyarladığım Code Shogun sayesinde .

Faaliyetinizin OnClickListenerher zamanki gibi uygulanmasına izin verin :

public class SelectFilterActivity extends Activity implements OnClickListener {

  private static final int SWIPE_MIN_DISTANCE = 120;
  private static final int SWIPE_MAX_OFF_PATH = 250;
  private static final int SWIPE_THRESHOLD_VELOCITY = 200;
  private GestureDetector gestureDetector;
  View.OnTouchListener gestureListener;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /* ... */

    // Gesture detection
    gestureDetector = new GestureDetector(this, new MyGestureDetector());
    gestureListener = new View.OnTouchListener() {
      public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
      }
    };

  }

  class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
      try {
        if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
          return false;
        // right to left swipe
        if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
        } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
        }
      } catch (Exception e) {
         // nothing
      }
      return false;
    }

    @Override
    public boolean onDown(MotionEvent e) {
      return true;
    }
  }
}

Hareket dinleyicinizi ana düzene eklediğiniz tüm görünümlere ekleyin;

// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this); 
imageView.setOnTouchListener(gestureListener);

Hem onClick(View v)etkinliğin hem onFlingde hareket dinleyicisinin geçersiz kılınan yöntemlerine çarptığında huşu içinde izleyin .

public void onClick(View v) {
  Filter f = (Filter) v.getTag();
  FilterFullscreenActivity.show(this, input, f);
}

'Fırlatma' sonrası dans isteğe bağlıdır ancak teşvik edilir.


109
Bu kod için teşekkürler! Çok yardımcı oldu. Ancak, jestleri çalıştırmaya çalışırken çok çok sinir bozucu bir avla karşılaştım. SimpleOnGestureListener'ımda, hareketlerimden herhangi birinin kaydedilmesi için onDown'ı geçersiz kılmam gerekiyor. Sadece doğru dönebilir ama ben tanımlanması gerekir. Not: Api revizyonum mu yoksa donanımım mı bilmiyorum, ama HTC Droid Eris üzerinde 1,5 kullanıyorum.
Cdsboy

Kodunuzu denedim ve kaydırmam ya da tıklamam önemli değil (faremle, öykünücüde çalıştığım için), her zaman onClick yönteminde tanımladığım bir Tost alıyorum, bu yüzden emülatör, sürüklemesiz yalnızca tıklamaları algılar. Neden böyle?
lomza

Bu kodu denedim ve işe yaramadı. galeri görünümünde çocuk görünümlerinden birine bir onClick dinleyicisi uyguladığımda hala kaydırma yapamadım
Jonathan

Iomza: Break ifadeleri koymayı ve kodunuzu atlamayı denediniz mi?
IgorGanapolsky

Bir iç sınıf kullanmak için şeref! Çok temiz bir yaklaşım.
IgorGanapolsky

211

Yukarıdaki cevaplardan biri farklı piksel yoğunluğunun ele alınmasından bahsediyor, ancak kaydırma parametrelerini elle hesaplamayı öneriyor. ViewConfigurationSınıfı kullanarak sistemden gerçekten ölçeklendirilmiş, makul değerler elde edebileceğinizi belirtmek gerekir :

final ViewConfiguration vc = ViewConfiguration.get(getContext());
final int swipeMinDistance = vc.getScaledPagingTouchSlop();
final int swipeThresholdVelocity = vc.getScaledMinimumFlingVelocity();
final int swipeMaxOffPath = vc.getScaledTouchSlop();
// (there is also vc.getScaledMaximumFlingVelocity() one could check against)

Bu değerleri kullanmanın, uygulama ile sistemin geri kalanı arasında alay "hissinin" daha tutarlı olmasına neden olduğunu fark ettim.


11
Kullandığım swipeMinDistance = vc.getScaledPagingTouchSlop()ve swipeMaxOffPath = vc.getScaledTouchSlop().
Thomas Ahle

8
getScaledTouchSlopbana garip bir şekilde çok az ofset sonucu veriyor. Örneğin, 540 yüksek ekranda sadece 24 piksel, parmağınızla menzilde tutmak çok zor. : S
WonderCsabo

148

Bunu biraz farklı yapıyorum ve bunu uygulayan ekstra bir dedektör sınıfı yazdım. View.onTouchListener

onCreatebasitçe aşağıdaki gibi en düşük düzene eklemektir:

ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
lowestLayout = (RelativeLayout)this.findViewById(R.id.lowestLayout);
lowestLayout.setOnTouchListener(activitySwipeDetector);

burada id.lowestLayout, düzen hiyerarşisindeki en düşük görünüm için id.xxx'dir ve lowLayout, RelativeLayout olarak bildirilir

Ve sonra gerçek aktivite tokatlamak dedektör sınıfı var:

public class ActivitySwipeDetector implements View.OnTouchListener {

static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;

public ActivitySwipeDetector(Activity activity){
    this.activity = activity;
}

public void onRightSwipe(){
    Log.i(logTag, "RightToLeftSwipe!");
    activity.doSomething();
}

public void onLeftSwipe(){
    Log.i(logTag, "LeftToRightSwipe!");
    activity.doSomething();
}

public void onDownSwipe(){
    Log.i(logTag, "onTopToBottomSwipe!");
    activity.doSomething();
}

public void onUpSwipe(){
    Log.i(logTag, "onBottomToTopSwipe!");
    activity.doSomething();
}

public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

       // swipe horizontal?
        if(Math.abs(deltaX) > Math.abs(deltaY))
        {
            if(Math.abs(deltaX) > MIN_DISTANCE){
                // left or right
                if(deltaX > 0) { this.onRightSwipe(); return true; }
                if(deltaX < 0) { this.onLeftSwipe(); return true; }
            }
            else {
                    Log.i(logTag, "Horizontal Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                    return false; // We don't consume the event
            }
        }
        // swipe vertical?
        else 
        {
            if(Math.abs(deltaY) > MIN_DISTANCE){
                // top or down
                if(deltaY < 0) { this.onDownSwipe(); return true; }
                if(deltaY > 0) { this.onUpSwipe(); return true; }
            }
            else {
                    Log.i(logTag, "Vertical Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                    return false; // We don't consume the event
            }
        }

            return true;
        }
    }
    return false;
}

}

Benim için gerçekten iyi çalışıyor!


1
Bu aslında hareket işlevini uygulamamı çok daha kolay hale getirdi ve "daha az" kablolama gerektirdi: D Thanks @Thomas
nemesisfixx

5
Bu temiz bir yardımcı sınıf gibi görünüyor - ama sanırım dört ... swipe () yöntemleri arayüzleri olmalıdır
Someone Somewhere Somewhere Somewhere

2
bu geri dönüşler orada olmamalı ("etkinliği tüketmiyoruz" satırı), değil mi? Dikey kaydırma özelliğini devre dışı bırakır.
Marek Sebera

5
özellikle, onTouch () yöntemi. ilk olarak, delta X yeterince büyük değilse, delta Y'yi kontrol etmeden geri döner. sonuç, sol-sağ tokatlamaları asla tespit etmez. ikincisi, tokatlamak bulamazsanız da doğru dönmemelidir. üçüncüsü, eylemde doğru geri dönmemelidir. bu, onClick gibi diğer dinleyicilerin çalışmasını önler.
Jeffrey Blattman

1
@Piotr, referansı tutan nesne etkinliğin kendisiyle aynı kapsamda olduğu sürece sorun değildir. sorun, örneğin statik bir üyeden olduğu gibi, etkinlikten daha geniş kapsamı olan bir yerde bir etkinliğe başvuru tuttuğunuzda oluşur.
Jeffrey Blattman

94

Thomas Fankhauser'ın çözümünü biraz değiştirdim ve tamir ettim

Tüm sistem iki dosyadan oluşur: SwipeInterface ve ActivitySwipeDetector


SwipeInterface.java

import android.view.View;

public interface SwipeInterface {

    public void bottom2top(View v);

    public void left2right(View v);

    public void right2left(View v);

    public void top2bottom(View v);

}

detektör

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class ActivitySwipeDetector implements View.OnTouchListener {

    static final String logTag = "ActivitySwipeDetector";
    private SwipeInterface activity;
    static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;

    public ActivitySwipeDetector(SwipeInterface activity){
        this.activity = activity;
    }

    public void onRightToLeftSwipe(View v){
        Log.i(logTag, "RightToLeftSwipe!");
        activity.right2left(v);
    }

    public void onLeftToRightSwipe(View v){
        Log.i(logTag, "LeftToRightSwipe!");
        activity.left2right(v);
    }

    public void onTopToBottomSwipe(View v){
        Log.i(logTag, "onTopToBottomSwipe!");
        activity.top2bottom(v);
    }

    public void onBottomToTopSwipe(View v){
        Log.i(logTag, "onBottomToTopSwipe!");
        activity.bottom2top(v);
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // swipe horizontal?
            if(Math.abs(deltaX) > MIN_DISTANCE){
                // left or right
                if(deltaX < 0) { this.onLeftToRightSwipe(v); return true; }
                if(deltaX > 0) { this.onRightToLeftSwipe(v); return true; }
            }
            else {
                Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
            }

            // swipe vertical?
            if(Math.abs(deltaY) > MIN_DISTANCE){
                // top or down
                if(deltaY < 0) { this.onTopToBottomSwipe(v); return true; }
                if(deltaY > 0) { this.onBottomToTopSwipe(v); return true; }
            }
            else {
                Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                v.performClick();
            }
        }
        }
        return false;
    }

}

şu şekilde kullanılır:

ActivitySwipeDetector swipe = new ActivitySwipeDetector(this);
LinearLayout swipe_layout = (LinearLayout) findViewById(R.id.swipe_layout);
swipe_layout.setOnTouchListener(swipe);

Ve uygulamada SwipeInterface'tenActivity yöntemler uygulamanız gerekir ve Swipe Olayını hangi görünümde çağırdığınızı öğrenebilirsiniz .

@Override
public void left2right(View v) {
    switch(v.getId()){
        case R.id.swipe_layout:
            // do your stuff here
        break;
    }       
}

Tekrar biraz değiştirdim v.performClick();, aynı görünümde ayarlanmışsa OnClickListener'a olay tüketmek için kullanılana bakın
Marek Sebera

Merhaba, ben tamamen yeni başlayan biriyim, bu yüzden bu soru gerçekten açık veya önemsiz olabilir, ancak lütfen cevaplayın. Yazdığınız bölüm şu şekilde kullanılır: ActivitySwipeDetector swipe = new ActivitySwipeDetector (this); Bu ifade MainActivity'nin bir parçası olacak, değil mi? Sonra, "bu" MainActivity'nin bir faaliyeti olacaktır. Oysa kurucu SwipeInterface örneğini alır. Lütfen bana yardım et. Çok teşekkürler.
Chocolava

@Chocolava yeni bir soru oluşturmak, yorum böyle sormak için iyi bir yer değil.
Marek Sebera

@MarekSebera bu ScrollView & ListView ile çalışmaz mı? Onlarla nasıl başa çıkılır?
Duc Tran

@silentbang tekrar, bu tür sorular sormak için yer değil. lütfen yeni soru dizisi oluşturun.
Marek Sebera

65

Yukarıdaki kaydırma hareketi dedektörü kodu çok kullanışlıdır! Bununla birlikte (REL_SWIPE), mutlak değerler yerine aşağıdaki göreceli değerleri kullanarak bu çözüm yoğunluğunu agnostik yapmak isteyebilirsiniz(SWIPE_)

DisplayMetrics dm = getResources().getDisplayMetrics();

int REL_SWIPE_MIN_DISTANCE = (int)(SWIPE_MIN_DISTANCE * dm.densityDpi / 160.0f);
int REL_SWIPE_MAX_OFF_PATH = (int)(SWIPE_MAX_OFF_PATH * dm.densityDpi / 160.0f);
int REL_SWIPE_THRESHOLD_VELOCITY = (int)(SWIPE_THRESHOLD_VELOCITY * dm.densityDpi / 160.0f);

8
Bunu getirmek için +1. DensityMetrics.densityDpi'nin API 4'te tanıtıldığını unutmayın. API 1 ile geriye dönük uyumluluk için bunun yerine DensityMetrics.density öğesini kullanın. Bu daha sonra hesaplamayı yalnızca SWIPE_MIN_DISTANCE * dm.density olacak şekilde değiştirir.
Thane Marşı

160.0f sayısını nereden buldunuz?
IgorGanapolsky

developer.android.com/guide/practices/screens_support.html Yoğunluktan bağımsız piksel (dp) dp birimlerinin ekran piksellerine dönüştürülmesi basittir: px = dp * (dpi / 160)
paiego

Bunu her yerde arıyordum. İnternette onFling () örneği HAYIR, bu da zayıf UX'e yol açacaktır. Teşekkürler!
Sandy

160.0f, DP'nin (yoğunluktan bağımsız pikseller) dayandığı standart yoğunluk olan 160 DPI'den gelir. public static final int DENSITY_MEDIUM API seviye 4'e eklendi Orta yoğunluklu ekranlar için standart sayısal DPI. Sabit Değer: 160 (0x000000a0)
paiego

35

Thomas Fankhauser ve Marek Sebera tarafından önerilen çözüm versiyonum (dikey swipe işlemez):

SwipeInterface.java

import android.view.View;

public interface SwipeInterface {

    public void onLeftToRight(View v);

    public void onRightToLeft(View v);
}

ActivitySwipeDetector.java

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

public class ActivitySwipeDetector implements View.OnTouchListener {

    static final String logTag = "ActivitySwipeDetector";
    private SwipeInterface activity;
    private float downX, downY;
    private long timeDown;
    private final float MIN_DISTANCE;
    private final int VELOCITY;
    private final float MAX_OFF_PATH;

    public ActivitySwipeDetector(Context context, SwipeInterface activity){
        this.activity = activity;
        final ViewConfiguration vc = ViewConfiguration.get(context);
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        MIN_DISTANCE = vc.getScaledPagingTouchSlop() * dm.density;
        VELOCITY = vc.getScaledMinimumFlingVelocity();
        MAX_OFF_PATH = MIN_DISTANCE * 2;            
    }

    public void onRightToLeftSwipe(View v){
        Log.i(logTag, "RightToLeftSwipe!");
        activity.onRightToLeft(v);
    }

    public void onLeftToRightSwipe(View v){
        Log.i(logTag, "LeftToRightSwipe!");
        activity.onLeftToRight(v);
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            Log.d("onTouch", "ACTION_DOWN");
            timeDown = System.currentTimeMillis();
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            Log.d("onTouch", "ACTION_UP");
            long timeUp = System.currentTimeMillis();
            float upX = event.getX();
            float upY = event.getY();

            float deltaX = downX - upX;
            float absDeltaX = Math.abs(deltaX); 
            float deltaY = downY - upY;
            float absDeltaY = Math.abs(deltaY);

            long time = timeUp - timeDown;

            if (absDeltaY > MAX_OFF_PATH) {
                Log.i(logTag, String.format("absDeltaY=%.2f, MAX_OFF_PATH=%.2f", absDeltaY, MAX_OFF_PATH));
                return v.performClick();
            }

            final long M_SEC = 1000;
            if (absDeltaX > MIN_DISTANCE && absDeltaX > time * VELOCITY / M_SEC) {
                if(deltaX < 0) { this.onLeftToRightSwipe(v); return true; }
                if(deltaX > 0) { this.onRightToLeftSwipe(v); return true; }
            } else {
                Log.i(logTag, String.format("absDeltaX=%.2f, MIN_DISTANCE=%.2f, absDeltaX > MIN_DISTANCE=%b", absDeltaX, MIN_DISTANCE, (absDeltaX > MIN_DISTANCE)));
                Log.i(logTag, String.format("absDeltaX=%.2f, time=%d, VELOCITY=%d, time*VELOCITY/M_SEC=%d, absDeltaX > time * VELOCITY / M_SEC=%b", absDeltaX, time, VELOCITY, time * VELOCITY / M_SEC, (absDeltaX > time * VELOCITY / M_SEC)));
            }

        }
        }
        return false;
    }

}

Herkes bana dersi nasıl arayacağımı söyleyebilir mi? ActivitySwipeDetector swipe = yeni ActivitySwipeDetector (this); açıkçası böyle bir kurucu olarak hata veriyor. ActivitySwipeDetector vermeli miyim swipe = new ActivitySwipeDetector (this, null);
abdfahim

@AbdullahFahim ActivitySwipeDetector (this, YourActivity.this);
Anton Kashpor

25

Bu soru biraz eski ve Temmuz 2011'de Google Uyumluluk Paketi, revizyon 3) içermektedir ViewPageryukarı Android 1.6 ile bu işler. GestureListenerBu soru için gönderilen cevaplar Android'deki çok şık hissetmiyorum. Android Galerisi'ndeki fotoğraflar arasında geçiş yapmak veya yeni Play Market uygulamasında görünümler arasında geçiş yapmak için kullanılan kodu arıyorsanız kesinlikle ViewPager.

Daha fazla bilgi için bazı bağlantılar:


ViewPager ile ilgili bir sorun, fırlatma hareketi için mesafe ve hız parametreleri üzerinde hiçbir kontrolünüz olmamasıdır.
almalkawi

ViewPager galeride kullanılmıyor.
Anthony

18

Tüm hareketler için doğrudan kullanabileceğiniz yerleşik bir arayüz var:
Temel düzey kullanıcı için bir açıklama: resim açıklamasını buraya girin Her ikisinin de farklı olduğunu seçerken dikkatli olun 2 ithalat var resim açıklamasını buraya girin resim açıklamasını buraya girin


1
Ve sonraki adımlar nelerdir? Bu dinleyiciyi belirli bir görünüme nasıl ayarlayabilirim? Ya bu görüş bir parçanın parçasıysa?
Stan

16

Web (ve bu sayfa) üzerinde ViewConfiguration'ı kullanmak için bazı öneriler var. için cihaz ölçeğinde bir değere sahip olmak için getScaledTouchSlop ()SWIPE_MIN_DISTANCE .

getScaledTouchSlop()" kaydırma " için tasarlanmıştır eşiği" mesafesi değil. Kaydırma eşik mesafesi, "sayfa arasında sallanma" eşik mesafesinden daha küçük olmalıdır. Örneğin, bu işlev Samsung GS2 cihazımda 12 piksel döndürür ve bu sayfada alıntılanan örnekler yaklaşık 100 pikseldir.

API Seviye 8 (Android 2.2, Froyo) ile, getScaledPagingTouchSlop()sayfa kaydırma için tasarlanmıştır. Cihazımda 24 (piksel) döndürüyor. API Düzeyi <8 düzeyindeyseniz, "2 * getScaledTouchSlop()" değerinin "standart" kaydırma eşiği olması gerektiğini düşünüyorum . Ancak küçük ekranlı uygulamamın kullanıcıları bana bunun çok az olduğunu söyledi ... Uygulamamda olduğu gibi, dikey olarak kaydırabilir ve sayfayı yatay olarak değiştirebilirsiniz. Önerilen değerle, bazen sayfayı kaydırmak yerine değiştirirler.


13

Ayrıca küçük bir gelişme olarak.

Try / catch bloğunun ana nedeni, e1'in ilk hareket için boş olabilmesidir. try / catch'e ek olarak, null ve return için bir test ekleyin. aşağıdakine benzer

if (e1 == null || e2 == null) return false;
try {
...
} catch (Exception e) {}
return false;

12

Burada birçok mükemmel bilgi var. Ne yazık ki bu fling-işleme kodunun birçoğu, bunun birçok uygulama için gerekli olduğunu düşünmesine rağmen, çeşitli tamamlama durumlarındaki çeşitli sitelere dağılmıştır.

Bir zaman oluşturmak için zaman ayırdım Uygun koşulların karşılandığını doğrulayan fling dinleyicisi ayırdım . Döndürmelerin sayfa kaydırmaları eşiğini karşıladığından emin olmak için daha fazla kontrol ekleyen bir sayfa savurma dinleyicisi ekledim . Bu dinleyicilerin her ikisi de, hareketleri yatay veya dikey eksene kolayca kısıtlamanızı sağlar. Kayan görüntüler için bir görünümde nasıl kullanıldığını görebilirsiniz . Buradaki insanların araştırmanın çoğunu yaptığını kabul ediyorum --- sadece kullanılabilir bir kütüphaneye koydum.

Bu son birkaç gün Android kodlama ilk bıçaklama temsil; daha fazlasını bekle gelmek.


2 parmakla kaydırma hareketi uygulamak istiyorum. Lütfen bana yardım et!
Gaurav Arora

12

Bu, çalışan bir uygulama isterse, üstteki iki cevabın birleşik cevabıdır.

package com.yourapplication;

import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

public abstract class OnSwipeListener implements View.OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeListener(Context context){
        gestureDetector = new GestureDetector(context, new OnSwipeGestureListener(context));
        gestureDetector.setIsLongpressEnabled(false);
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class OnSwipeGestureListener extends GestureDetector.SimpleOnGestureListener {

        private final int minSwipeDelta;
        private final int minSwipeVelocity;
        private final int maxSwipeVelocity;

        private OnSwipeGestureListener(Context context) {
            ViewConfiguration configuration = ViewConfiguration.get(context);
            // We think a swipe scrolls a full page.
            //minSwipeDelta = configuration.getScaledTouchSlop();
            minSwipeDelta = configuration.getScaledPagingTouchSlop();
            minSwipeVelocity = configuration.getScaledMinimumFlingVelocity();
            maxSwipeVelocity = configuration.getScaledMaximumFlingVelocity();
        }

        @Override
        public boolean onDown(MotionEvent event) {
            // Return true because we want system to report subsequent events to us.
            return true;
        }

        // NOTE: see http://stackoverflow.com/questions/937313/android-basic-gesture-detection
        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX,
                               float velocityY) {

            boolean result = false;
            try {
                float deltaX = event2.getX() - event1.getX();
                float deltaY = event2.getY() - event1.getY();
                float absVelocityX = Math.abs(velocityX);
                float absVelocityY = Math.abs(velocityY);
                float absDeltaX = Math.abs(deltaX);
                float absDeltaY = Math.abs(deltaY);
                if (absDeltaX > absDeltaY) {
                    if (absDeltaX > minSwipeDelta && absVelocityX > minSwipeVelocity
                            && absVelocityX < maxSwipeVelocity) {
                        if (deltaX < 0) {
                            onSwipeLeft();
                        } else {
                            onSwipeRight();
                        }
                    }
                    result = true;
                } else if (absDeltaY > minSwipeDelta && absVelocityY > minSwipeVelocity
                        && absVelocityY < maxSwipeVelocity) {
                    if (deltaY < 0) {
                        onSwipeTop();
                    } else {
                        onSwipeBottom();
                    }
                }
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    }

    public void onSwipeLeft() {}

    public void onSwipeRight() {}

    public void onSwipeTop() {}

    public void onSwipeBottom() {}
}

Gerçekten iyi bir uygulama için teşekkür ederim. Ayrıca ben kontrol etmek öneririm absDeltaY > minSwipeDelta, absVelocityY > minSwipeVelocity, absVelocityY < maxSwipeVelocitysadece durumda eğer minSwipeDelta ! = getScaledTouchSlop , minSwipeVelocity ! = getScaledMinimumFlingVelocity , maxSwipeVelocity ! = getScaledMaximumFlingVelocity , Yani kontrol etmek yalnızca bu sözde “varsayılan” (Ben getScaledTouchSlop, getScaledMinimumFlingVelocity, getScaledMaximumFlingVelocity demek) değerleri uygun ölçekli veya değiştirilir senin kendi isteği.
Elia12345

Nokta göre olmasıdır kaynak kodu , adı geçen "varsayılan" değerler zaten GestureDetector tarafından kontrol edilir ve bunlar teyit eğer OnFling tetikleme sadece durumunda gerçekleşir arada (sadece tetiklenir ACTION_UPdeğil, ACTION_MOVEya ACTION_POINTER_UP, yani yalnızca tamamen gerçekleşen hareketin bir sonucu). (Diğer API sürümlerini kontrol etmedim, bu yüzden yorumlar takdir edildi).
Elia12345

11

Döndürme , tıklama, uzun tıklama ve özel etkinlikleri işlemek için droidQuery kitaplığını kullanabilirsiniz . Uygulama aşağıdaki önceki cevabım üzerine inşa edilmiştir, ancak droidQuery kaygan ve basit bir sözdizimi sağlar:

//global variables    private boolean isSwiping = false;
private SwipeDetector.Direction swipeDirection = null;
private View v;//must be instantiated before next call.

//swipe-handling code
$.with(v).swipe(new Function() {
    @Override
    public void invoke($ droidQuery, Object... params) {
        if (params[0] == SwipeDetector.Direction.START)
            isSwiping = true;
        else if (params[0] == SwipeDetector.Direction.STOP) {
            if (isSwiping) {                    isSwiping = false;
                if (swipeDirection != null) {
                    switch(swipeDirection) {
                        case DOWN :                                //TODO: Down swipe complete, so do something
                            break;
                        case UP :
                            //TODO: Up swipe complete, so do something
                            break;
                        case LEFT :
                            //TODO: Left swipe complete, so do something
                            break;
                        case RIGHT :
                            //TODO: Right swipe complete, so do something
                            break;
                        default :                                break;
                    }
                }                }
        }
        else {
            swipeDirection = (SwipeDetector.Direction) params[0];
        }
    }
});

Orijinal Yanıt

Bu cevap, diğer yanıtların bileşenlerinin bir kombinasyonunu kullanır. SwipeDetectorOlayları dinlemek için iç bir arayüze sahip olan sınıftan oluşur . Ben de RelativeLayouta View's geçersiz kılmak için nasıl göstermekonTouch manyetik etkinliklerle (tıklama veya uzun tıklama gibi) diğer tespit olaylar hem de izin vermek için bir yöntem.

SwipeDetector

package self.philbrown;

import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

/**
 * Detect Swipes on a per-view basis. Based on original code by Thomas Fankhauser on StackOverflow.com,
 * with adaptations by other authors (see link).
 * @author Phil Brown
 * @see <a href="http://stackoverflow.com/questions/937313/android-basic-gesture-detection">android-basic-gesture-detection</a>
 */
public class SwipeDetector implements View.OnTouchListener
{
    /**
     * The minimum distance a finger must travel in order to register a swipe event.
     */
    private int minSwipeDistance;

    /** Maintains a reference to the first detected down touch event. */
    private float downX, downY;

    /** Maintains a reference to the first detected up touch event. */
    private float upX, upY;

    /** provides access to size and dimension contants */
    private ViewConfiguration config;

    /**
     * provides callbacks to a listener class for various swipe gestures.
     */
    private SwipeListener listener;

    public SwipeDetector(SwipeListener listener)
    {
        this.listener = listener;
    }


    /**
     * {@inheritDoc}
     */
    public boolean onTouch(View v, MotionEvent event)
    {
        if (config == null)
        {
                config = ViewConfiguration.get(v.getContext());
                minSwipeDistance = config.getScaledTouchSlop();
        }

        switch(event.getAction())
        {
        case MotionEvent.ACTION_DOWN:
            downX = event.getX();
            downY = event.getY();
            return true;
        case MotionEvent.ACTION_UP:
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // swipe horizontal?
            if(Math.abs(deltaX) > minSwipeDistance)
            {
                // left or right
                if (deltaX < 0)
                {
                        if (listener != null)
                        {
                                listener.onRightSwipe(v);
                                return true;
                        }
                }
                if (deltaX > 0)
                {
                        if (listener != null)
                        {
                                listener.onLeftSwipe(v);
                                return true;
                        }
                }
            }

            // swipe vertical?
            if(Math.abs(deltaY) > minSwipeDistance)
            {
                // top or down
                if (deltaY < 0)
                {
                        if (listener != null)
                        {
                                listener.onDownSwipe(v);
                                return true;
                        }
                }
                if (deltaY > 0)
                {
                        if (listener != null)
                        {
                                listener.onUpSwipe(v);
                                return true;
                        }
                }
            }
        }
        return false;
    }

    /**
     * Provides callbacks to a registered listener for swipe events in {@link SwipeDetector}
     * @author Phil Brown
     */
    public interface SwipeListener
    {
        /** Callback for registering a new swipe motion from the bottom of the view toward its top. */
        public void onUpSwipe(View v);
        /** Callback for registering a new swipe motion from the left of the view toward its right. */
        public void onRightSwipe(View v);
        /** Callback for registering a new swipe motion from the right of the view toward its left. */
        public void onLeftSwipe(View v);
        /** Callback for registering a new swipe motion from the top of the view toward its bottom. */
        public void onDownSwipe(View v);
    }
}

Swipe Interceptor Görüntüle

package self.philbrown;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;

import com.npeinc.module_NPECore.model.SwipeDetector;
import com.npeinc.module_NPECore.model.SwipeDetector.SwipeListener;

/**
 * View subclass used for handling all touches (swipes and others)
 * @author Phil Brown
 */
public class SwipeInterceptorView extends RelativeLayout
{
    private SwipeDetector swiper = null;

    public void setSwipeListener(SwipeListener listener)
    {
        if (swiper == null)
            swiper = new SwipeDetector(listener);
    }

    public SwipeInterceptorView(Context context) {
        super(context);
    }

    public SwipeInterceptorView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeInterceptorView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e)
    {
        boolean swipe = false, touch = false;
        if (swiper != null)
            swipe = swiper.onTouch(this, e);
        touch = super.onTouchEvent(e);
        return swipe || touch;
    }
}

1
Tıklanabilir öğeler içeren bir görünümde bu uygulamayı denedim. Kaydırılabilir bir öğenin (örneğin, onItemClick dinleyicisinin kayıtlı olduğu bir liste görünümü) üzerinde hızlıca kaydırma başladığında, onTouchEvent hiçbir zaman çağrılmaz. Böylece, kullanıcı benim için talihsiz bir tıklanabilir eleman üzerinde bir tokatlamak başlatamaz ve ben hala nasıl çalışacağını anlamaya çalışıyorum, çünkü tıklanabilir elemanlarımız biraz görüş alanı kaplıyor ve hala kaydırma desteği istiyoruz tüm görünüm için. Bir tokatlamak tıklanabilir bir öğenin üzerinden başlamazsa, mükemmel çalışır.
Lo-Tan

@ Lo-Tan, bunun nedeni, tıklanabilir öğenizin bir alt öğe görünümü olması ve bu nedenle en üstte olmasıdır SwipeInterceptorView, bu nedenle önce tıklaması işlenir. Bunu, kendi tıklama mekanizmanızı uygulayarak uygulayarak düzeltebilirsiniz onTouchListenerveya bir çözüm olarak, tıklamalar yerine uzun tıklamaları dinleyebilirsiniz (bkz. View.setOnLongClickListener).
Phil

Aslında şu anda deniyorum. Veya bir sürükleme başlatırlarsa tıklama olayını iptal etme :) Çok teşekkürler.
Lo-Tan

Bir çözüm, kaydırma detektörünü uygulamanızdaki her görünüme eklemektir. Bir diğeri de SwipeInterceptorView içinde onInterceptTouchEvent uygulamaktır .
Edward Falk

7

Cevap vermek için çok geç olduğunu biliyorum ama yine de ListView için Swipe Touch Listener'ı nasıl kullanacağım .

Referans: Yok edici13 (bu sayfadaki cevaplardan biri)

Bir ActivitySwipeDetector.class yapın

package com.example.wocketapp;

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

public class ActivitySwipeDetector implements View.OnTouchListener 
{
    static final String logTag = "SwipeDetector";
    private SwipeInterface activity;
    private float downX, downY;
    private long timeDown;
    private final float MIN_DISTANCE;
    private final int VELOCITY;
    private final float MAX_OFF_PATH;

    public ActivitySwipeDetector(Context context, SwipeInterface activity)
    {
        this.activity = activity;
        final ViewConfiguration vc = ViewConfiguration.get(context);
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        MIN_DISTANCE = vc.getScaledPagingTouchSlop() * dm.density;
        VELOCITY = vc.getScaledMinimumFlingVelocity();
        MAX_OFF_PATH = MIN_DISTANCE * 2;
    }

    public void onRightToLeftSwipe(View v) 
    {
        Log.i(logTag, "RightToLeftSwipe!");
        activity.onRightToLeft(v);
    }

    public void onLeftToRightSwipe(View v) 
    {
        Log.i(logTag, "LeftToRightSwipe!");
        activity.onLeftToRight(v);
    }

    public boolean onTouch(View v, MotionEvent event) 
    {
        switch (event.getAction()) 
        {
            case MotionEvent.ACTION_DOWN:
            {
                Log.d("onTouch", "ACTION_DOWN");
                timeDown = System.currentTimeMillis();
                downX = event.getX();
                downY = event.getY();
                v.getParent().requestDisallowInterceptTouchEvent(false);
                return true;
            }

        case MotionEvent.ACTION_MOVE:
            {
                float y_up = event.getY();
                float deltaY = y_up - downY;
                float absDeltaYMove = Math.abs(deltaY);

                if (absDeltaYMove > 60) 
                {
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                } 
                else
                {
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                }
            }

            break;

            case MotionEvent.ACTION_UP: 
            {
                Log.d("onTouch", "ACTION_UP");
                long timeUp = System.currentTimeMillis();
                float upX = event.getX();
                float upY = event.getY();

                float deltaX = downX - upX;
                float absDeltaX = Math.abs(deltaX);
                float deltaY = downY - upY;
                float absDeltaY = Math.abs(deltaY);

                long time = timeUp - timeDown;

                if (absDeltaY > MAX_OFF_PATH) 
                {
                    Log.e(logTag, String.format(
                            "absDeltaY=%.2f, MAX_OFF_PATH=%.2f", absDeltaY,
                            MAX_OFF_PATH));
                    return v.performClick();
                }

                final long M_SEC = 1000;
                if (absDeltaX > MIN_DISTANCE && absDeltaX > time * VELOCITY / M_SEC) 
                {
                     v.getParent().requestDisallowInterceptTouchEvent(true);
                    if (deltaX < 0) 
                    {
                        this.onLeftToRightSwipe(v);
                        return true;
                    }
                    if (deltaX > 0) 
                    {
                        this.onRightToLeftSwipe(v);
                        return true;
                    }
                }
                else 
                {
                    Log.i(logTag,
                            String.format(
                                    "absDeltaX=%.2f, MIN_DISTANCE=%.2f, absDeltaX > MIN_DISTANCE=%b",
                                    absDeltaX, MIN_DISTANCE,
                                    (absDeltaX > MIN_DISTANCE)));
                    Log.i(logTag,
                            String.format(
                                    "absDeltaX=%.2f, time=%d, VELOCITY=%d, time*VELOCITY/M_SEC=%d, absDeltaX > time * VELOCITY / M_SEC=%b",
                                    absDeltaX, time, VELOCITY, time * VELOCITY
                                            / M_SEC, (absDeltaX > time * VELOCITY
                                            / M_SEC)));
                }

                 v.getParent().requestDisallowInterceptTouchEvent(false);

            }
        }
        return false;
    }
    public interface SwipeInterface 
    {

        public void onLeftToRight(View v);

        public void onRightToLeft(View v);
    }

}

Etkinlik sınıfınızdan şu şekilde çağırın:

yourLayout.setOnTouchListener(new ActivitySwipeDetector(this, your_activity.this));

Ve size iki override yöntemi verecek olan SwipeInterface'i uygulamayı unutmayın :

    @Override
    public void onLeftToRight(View v) 
    {
        Log.e("TAG", "L to R");
    }

    @Override
    public void onRightToLeft(View v) 
    {
        Log.e("TAG", "R to L");
    }

Ben MAX_OFF_PATH = 5 * vc.getScaledPagingTouchSlop()a hafif bir yay doğal olarak seyahat bir başparmak tokatlamak için daha rahat buluyorum .
qix

4

Hareketler, dokunmatik ekran ile kullanıcı arasındaki etkileşimi tetikleyen ince hareketlerdir. Ekrandaki ilk dokunuş ile son parmağın yüzeyden çıktığı noktaya kadar sürer.

Android adında bir sınıf ile bize sağlar GestureDetector biz gibi ortak hareketlerini algılayabilir kullanarak uzun ve kısa basın, çift musluklar, vs, aşağı dokunarak ve yukarı, dikey ve yatay olarak (kaçamaktı) kaydırarak . ve dinleyicileri onlara iliştirin.

Etkinlik sınıfımızın GestureDetector.OnDoubleTapListener (çift dokunma hareketi algılaması için) ve GestureDetector.OnGestureListener arabirimlerini uygulamasını ve tüm soyut yöntemleri uygulamasını sağlayın . https://developer.android.com/training/gestures/detector.html adresini ziyaret edebilirsiniz . Nezaket

Demo Testi için. GestureDetectorDemo


4

Ayrı bir sınıf oluşturmak veya kod karmaşıklığını
yapmak istemiyorsanız, OnTouchListener içinde bir GestureDetector değişkeni oluşturabilir ve kodunuzu daha kolay hale getirebilirsiniz

namVyuVar, listeyi ayarlamanız gereken Görünüm'ün herhangi bir adı olabilir

namVyuVar.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View view, MotionEvent MsnEvtPsgVal)
    {
        flingActionVar.onTouchEvent(MsnEvtPsgVal);
        return true;
    }

    GestureDetector flingActionVar = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener()
    {
        private static final int flingActionMinDstVac = 120;
        private static final int flingActionMinSpdVac = 200;

        @Override
        public boolean onFling(MotionEvent fstMsnEvtPsgVal, MotionEvent lstMsnEvtPsgVal, float flingActionXcoSpdPsgVal, float flingActionYcoSpdPsgVal)
        {
            if(fstMsnEvtPsgVal.getX() - lstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Right to Left fling

                return false;
            }
            else if (lstMsnEvtPsgVal.getX() - fstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Left to Right fling

                return false;
            }

            if(fstMsnEvtPsgVal.getY() - lstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Bottom to Top fling

                return false;
            }
            else if (lstMsnEvtPsgVal.getY() - fstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Top to Bottom fling

                return false;
            }
            return false;
        }
    });
});

3

Herkese: MotionEvent.ACTION_CANCEL durumunu unutma :

ACTION_UP olmadan% 30 swipe çağrı yapıyor

ve bu durumda ACTION_UP değerine eşit


2

Daha genel bir Sınıf oluşturdum, Tomas'ın sınıfını aldım ve Aktivitenize veya Parçanıza olaylar gönderen bir Arayüz ekledim. dinleyiciyi yapıcıya kaydeder, bu nedenle arabirimi uyguladığınızdan emin olun, yoksa bir ClassCastException düzeltilecektir. arabirim, sınıfta tanımlanan dört son int'den birini döndürür ve etkinleştirildiği görünümü döndürür.

import android.app.Activity;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SwipeDetector implements View.OnTouchListener{

    static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;
    public final static int RIGHT_TO_LEFT=1;
    public final static int LEFT_TO_RIGHT=2;
    public final static int TOP_TO_BOTTOM=3;
    public final static int BOTTOM_TO_TOP=4;
    private View v;

    private onSwipeEvent swipeEventListener;


    public SwipeDetector(Activity activity,View v){
        try{
            swipeEventListener=(onSwipeEvent)activity;
        }
        catch(ClassCastException e)
        {
            Log.e("ClassCastException",activity.toString()+" must implement SwipeDetector.onSwipeEvent");
        } 
        this.v=v;
    }
    public SwipeDetector(Fragment fragment,View v){
        try{
            swipeEventListener=(onSwipeEvent)fragment;
        }
        catch(ClassCastException e)
        {
            Log.e("ClassCastException",fragment.toString()+" must implement SwipeDetector.onSwipeEvent");
        } 
        this.v=v;
    }


    public void onRightToLeftSwipe(){   
        swipeEventListener.SwipeEventDetected(v,RIGHT_TO_LEFT);
    }

    public void onLeftToRightSwipe(){   
        swipeEventListener.SwipeEventDetected(v,LEFT_TO_RIGHT);
    }

    public void onTopToBottomSwipe(){   
        swipeEventListener.SwipeEventDetected(v,TOP_TO_BOTTOM);
    }

    public void onBottomToTopSwipe(){
        swipeEventListener.SwipeEventDetected(v,BOTTOM_TO_TOP);
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            //HORIZONTAL SCROLL
            if(Math.abs(deltaX) > Math.abs(deltaY))
            {
                if(Math.abs(deltaX) > MIN_DISTANCE){
                    // left or right
                    if(deltaX < 0) 
                    {
                        this.onLeftToRightSwipe();
                        return true;
                    }
                    if(deltaX > 0) {
                        this.onRightToLeftSwipe();
                        return true; 
                    }
                }
                else {
                    //not long enough swipe...
                    return false; 
                }
            }
            //VERTICAL SCROLL
            else 
            {
                if(Math.abs(deltaY) > MIN_DISTANCE){
                    // top or down
                    if(deltaY < 0) 
                    { this.onTopToBottomSwipe();
                    return true; 
                    }
                    if(deltaY > 0)
                    { this.onBottomToTopSwipe(); 
                    return true;
                    }
                }
                else {
                    //not long enough swipe...
                    return false;
                }
            }

            return true;
        }
        }
        return false;
    }
    public interface onSwipeEvent
    {
        public void SwipeEventDetected(View v , int SwipeType);
    }

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.