2013-01-23 12 views
7

OnTouch hareketlerini işlemek için ve onClick olaylarını görmem gereken bir görünüm var. Bunu başarmanın doğru yolu nedir?OnTouch ve onClick olaylarını Android ile alma

Görünümde bir onTouchListener ve bir onClickListener var. Görüntüye her dokunduğumda, önce onTouch olayı tetiklenir ve daha sonra onClick. Ancak, onTouch olay işleyicisinden true ya da false ya dönmek zorundayım. Dönen true, olayın tüketildiği anlamına gelir, böylece android etkinlik sistemi etkinliği daha fazla yaymayacaktır.

nedenle, bir onClick olay benim onTouch olay işleyicisi içinde true döndüğünüzde en az benim onClick dinleyici tetiklenir asla, hiçbir zaman üretilmez. Öte yandan, false geri dönen bir seçenek yoktur, zira bu, onTouch dinleyicinin bir hareketi tanımak için gerekli olan başka olayları almasını engeller. Bunu çözmenin alışılmış yolu nedir?

+1

Neden VEYA onClick'e ihtiyacınız var? Elbette sadece onTouch yeterli olurdu. – JDx

+0

[GestureDetector] hakkında (http://developer.android.com/reference/android/view/GestureDetector.html)? – keyser

+0

@JDx Bir 'onTouchListener'den bir tıklamayı nasıl tanımam gerekiyor? Tıklama, en az iki dokunma olayından oluşan bir dizidir; burada "ACTION_DOWN" etkinliği daha sonra ACTION_UP' etkinliğiyle aynı konumda (veya en azından aynı görünümde) tetiklenir. Elbette, bunu uygulayabilir ve başka bir çözüm yoksa ben de olurum. Ama sorum şu, bu senaryo için yerleşik bir çözüm var mı? – theV0ID

cevap

5

onTouchListener kullanırsanız, onClickListener'u kullanmanız gerekmez. onClickListener'da ne yapar, dokunma olayını ve olay etkinliklerini kontrol eder ve tıklamayı saptar. Yani, onClick’u kullanırken biraz iş yapmak istiyorsanız. eylemi filtreleyerek onTouchListener'da yapabilirsiniz.

public boolean onTouch(View v, MotionEvent event) { 
if (event.getAction() == MotionEvent.ACTION_DOWN) { 
    //this is touch 

} 
if (event.getAction() == MotionEvent.ACTION_UP) { 
    //this is click 

} 
return false; 
} 
+0

Bir 'onClick' olayını açıkça 'MotionEvent.ACTION_UP' bloğu içinden ateş etmek mümkün mü? – theV0ID

+0

Ve: ya benim görüşüm aslında bir "ViewGroup" ise ve çocuk görüşlerinin bir kısmının hala "onClick"-Event'i işlemesi gerekiyorsa? – theV0ID

+0

theV0ID, evet view.performClick() öğesini çağırmakla mümkündür. –

0

Sana onTouchlistener kullanın Eğer düğme, görüntü üzerinde bir olayı tetiklemek için tıklayın veya TextView'un istiyorsanız o zaman sadece OnClickListener ateş, OnClickListener veya tersine kullanmaya ihtiyacım yok, jdx katılıyorum. sürükleme ve eğirme gibi bazı animasyonlar istiyorsanız, yüzeyin koordinatlarını almak için touchlistener'ı kullanın

+0

Daha önce de belirttiğim gibi: Görünümüm aslında bir ViewGroup ise ve çocuk görüşlerinin bir kısmının hala onClick-Event'i işlemesi gerekiyorsa? – theV0ID

+0

Onclick ve ontouch dinleyicisine sahip olmanız gereken durumlar var. ACTION_UP sırasında bir ontouch içinden bir tıklama olayı oluşturmak aynı şey değildir. – AndroidDev

6

GestureDetector'da doğrudan callOnClick() öğesini çağırabilirsiniz. View.callOnClick API'sı API düzeyi 15 gerektirir. Sadece bir deneyin.

// Create a Gesturedetector 
GestureDetector mGestureDetector = new GestureDetector(context, new MyGestureDetector()); 

// Add a OnTouchListener into view 
m_myViewer.setOnTouchListener(new OnTouchListener() 
{ 

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

private class MyGestureDetector extends GestureDetector.SimpleOnGestureListener 
{ 
    public boolean onSingleTapUp(MotionEvent e) { 
     // ---Call it directly--- 
     callOnClick(); 
     return false; 
    } 

    public void onLongPress(MotionEvent e) { 
    } 

    public boolean onDoubleTap(MotionEvent e) { 
     return false; 
    } 

    public boolean onDoubleTapEvent(MotionEvent e) { 
     return false; 
    } 

    public boolean onSingleTapConfirmed(MotionEvent e) { 
     return false; 

    } 

    public void onShowPress(MotionEvent e) { 
     LogUtil.d(TAG, "onShowPress"); 
    } 

    public boolean onDown(MotionEvent e) {    
     // Must return true to get matching events for this down event. 
     return true; 
    } 

    public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY) { 
     return super.onScroll(e1, e2, distanceX, distanceY); 
    }   

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     // do something 
     return super.onFling(e1, e2, velocityX, velocityY); 
    } 
} 
+0

'callOnClick' yöntemi tanımlandı? API'de, ne SimpleOnGestureListener'de ne de “GestureDetector” ınkilerinde bulamıyorum. – theV0ID

+0

View.callOnClick API, API düzeyi 15 gerektirir. Bunu bulabilirsiniz: http://developer.android.com/intl/zh-CN/reference/android/view/View.html#callOnClick(). SimpleOnGestureListener, GestureDetector.OnGestureListener'dan genişletilebilir, http://developer.android.com/intl/zh-CN/reference/android/view/GestureDetector.SimpleOnGestureListener.html – Autobots

0
isMove = false; 
case MotionEvent.ACTION_DOWN: 
//Your stuff 
isMove = false; 
case MotionEvent.ACTION_UP: 
if (!isMove || (Xdiff < 10 && Ydiff < 10) { 
view.performClick; //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little 
even when you just click it 
} 
case MotionEvent.ACTION_MOVE: 
isMove = true; 

başka bir yolu mesajları kullanmaktır. Bu Action_Down'da bir sayacı artırmak için bir iş parçacığı başlatır. Action_UP durumunda: iş parçacığını durdur/durdur. daha az 2 (diyelim veya eşik uygulamanıza göre) ya! isMove ardından tıklama fonksiyonu

4
@Override 
    public boolean onTouch(View v, MotionEvent event) { 


     switch (event.getAction()) { 
      case MotionEvent.ACTION_MOVE: 
       layOutParams.x = initialX + (int) (event.getRawX() - initialTouchX); 
       layOutParams.y = initialY + (int) (event.getRawY() - initialTouchY); 

       break; 
      case MotionEvent.ACTION_DOWN: 
       initialX = layOutParams.x; 
       initialY = layOutParams.y; 
       initialTouchX = event.getRawX(); 
       initialTouchY = event.getRawY(); 
       if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) { 
        return false;// to handle Click 
       } 
       break; 
      case MotionEvent.ACTION_UP: 
       if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) { 
        return false;// to handle Click 
       } 
       break; 

     } 
     return true; 

    } 
}; 
0

biz bayrak tabanlı uygulama kullanabilirsiniz çağırmak durumunda sayaç arayın. tokatlamak/sürükleyerek Action_Up'da işleyebilir ve bayrağı doğru yapabilir ve geri dönüş yapabiliriz. Action_Down'da tıklayın veya Dokunun aynı tanıtıcıya dokunun ve bayrağı yanlış olarak ayarlayın ve döndürün.

touchAndSwipe=false; 
     switch(e.getAction()){ 
     case MotionEvent.ACTION_MOVE:    
      break; 
     case MotionEvent.ACTION_DOWN:    
      x1 = e.getX(); 
      break; 
     case MotionEvent.ACTION_UP: 
      x2 = e.getX(); 
      float diff= x2-x1; 
       if(Math.abs(delta)>100){ 
       // Swipe 
       touchAndSwipe=true; 
       }else{ 
       touchAndSwipe=false; 
        }    
      break; 
     } 
     return touchAndSwipe; 
0

OnClick ve OnTouch'ı birlikte oluşturduğum özel bir klavye ile birlikte uygulayabiliyorum. Çalışmak için bir kod örneği eklemediğinden, bu koda bir göz atabilir ve bağlamınıza göre değiştirebilirsiniz.

Kodunuzun bir örneğini gönderirseniz, kullanımınız için aynı sonucu elde etmek için bu örneklemi değiştirebilirim. Android Geliştirme söz konusu olduğunda içerik her şeydir. Bu kod snippet'ine bir göz atın ve yardımcı olup olmadığını görün. Aksi takdirde kendi örneğinizi gönderin ve değişiklikleri yapacağım ve yanıtlayacağım.Olay göndermek veya değiştirilmesi gerekir başka bir bağlam tüketmeye arıyorsa

 View DefaultphaseLay() { 

     LinearLayout mViewFirstPhase = (LinearLayout) getLayoutInflater().inflate(R.layout.layout_default_phase, parent); 

     ksOne_btn_LiLay = (LinearLayout) mViewFirstPhase.findViewById(R.id.ksOne_btn_LiLay); 
     ksOne_btn = (Button) mViewFirstPhase.findViewById(R.id.ksOne_btn); 
     ksOne_btn.setOnClickListener(mCorkyListener); 
     ksOne_btn.setFocusableInTouchMode(true); 
     ksOne_btn.setFocusable(true); 
     ksOne_btn.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 

       if (event.getAction() == MotionEvent.ACTION_DOWN) { 
        playClick(keyCode); 
        //v.startAnimation(animScale); 
        //key_sound.start(); 
        xkeys_lay.setVisibility(View.GONE); 
        numkeys_lay.setVisibility(View.GONE); 
        if (Constants.HapticFeedbackConstant) { 
         myVib.vibrate(Constants.vibration_duration); 
        } 
       } else if (event.getAction() == MotionEvent.ACTION_UP) { 
        ksOne_btn.setFocusable(false); //Check This Added This In Attempt to Kill Selector on Action_Up 
        //playClick(-100); 
        //key_sound.pause(); 
       } 
       return false; 
      } 
     }); 

     ChangeKeyBackgroundMehods.initChange_Key_Background(ksOne_btn_LiLay); 
     ChangeFontStyle.initChange_fontStyle(ksOne_btn, getApplicationContext()); 
     ChangeFont_size.initChange_fontSize(ksOne_btn, getApplicationContext()); 

Bu tip alfa veya sayısal çıkış bağlamında için çalışır.

+0

adresinde bulabilirsiniz. eğer/else aşağıya bakarsanız, ancak alfa/sayısal ile kullanıyorsanız, basılan durumları ve geçiş durumlarını yönetdiğinizden emin olun, aksi takdirde EditText alanlarında çıktınızda çift karakterleri elde edersiniz. –