2012-07-10 14 views
17

Próbuję wykorzystać gesty w obrębie fragmentu; Mam wewnątrz FragmentActivity, który obsługuje mój fragment szczegółów. Próbuję się zdarzyć, gdy w widoku zostanie wykryte przesunięcie w celu zastąpienia danych w tym widoku poprzednim lub następnym wpisem.Fragment Androida onCreateView z gestami

Jeśli istnieje lepszy sposób postępowania z tym; Jestem za tym wszystkim. Jednak to, co się tutaj dzieje, to fakt, że metoda onFling nigdy nie jest wywoływana.

public static class DetailsFragment extends Fragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
     if (container == null) { 
      return null; 
     } 
     View v = inflater.inflate(R.layout.my_view, null, false); 
     final GestureDetector gesture = new GestureDetector(getActivity(), 
      new GestureDetector.SimpleOnGestureListener() { 
       @Override 
       public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
        float velocityY) { 

        final int SWIPE_MIN_DISTANCE = 120; 
        final int SWIPE_MAX_OFF_PATH = 250; 
        final int SWIPE_THRESHOLD_VELOCITY = 200; 
        try { 
         if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
          return false; 
         if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE 
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
          Log.i(Constants.APP_TAG, "Right to Left"); 
         } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE 
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
          Log.i(Constants.APP_TAG, "Left to Right"); 
          titles.showDetails(getPosition() - 1); 
         } 
        } catch (Exception e) { 
         // nothing 
        } 
        return super.onFling(e1, e2, velocityX, velocityY); 
       } 
      }); 

     v.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       return gesture.onTouchEvent(event); 
      } 
     }); 

     return v; 
    } 
} 

Odpowiedz

43

wygląda następująco wyjaśnia ten problem: Android: GestureDetector won't catch Gestures

Dodatkowo oto wynik:

Rozwiązaniem jest rzeczywiście nadpisać metodę onDown i return true; inaczej detektor gest zatrzyma się i nie wykrywa w górę:

 final GestureDetector gesture = new GestureDetector(getActivity(), 
      new GestureDetector.SimpleOnGestureListener() { 

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

       @Override 
       public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
        float velocityY) { 
        Log.i(Constants.APP_TAG, "onFling has been called!"); 
        final int SWIPE_MIN_DISTANCE = 120; 
        final int SWIPE_MAX_OFF_PATH = 250; 
        final int SWIPE_THRESHOLD_VELOCITY = 200; 
        try { 
         if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
          return false; 
         if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE 
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
          Log.i(Constants.APP_TAG, "Right to Left"); 
         } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE 
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
          Log.i(Constants.APP_TAG, "Left to Right"); 
         } 
        } catch (Exception e) { 
         // nothing 
        } 
        return super.onFling(e1, e2, velocityX, velocityY); 
       } 
      }); 

     v.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       return gesture.onTouchEvent(event); 
      } 
     }); 
+3

po prostu ciekawy: dlaczego nie ma odniesienia do zgubionego gestu? –

+1

@LemLordjeKo dlaczego zgubiono by odwołanie do 'gesta'? 'gest' jest trzymany jako odniesienie przez' View.OnTouchListener', który stworzyliśmy i który jest przechowywany jako odniesienie przez sam widok, 'v'. Java jest wystarczająco dojrzała, jeśli istnieje ścieżka do obiektu, prawie na pewno nie otrzyma GC. – bclymer

+0

Poniższy import jest potrzebny do działania powyższego fragmentu kodu: import android.view.View.OnTouchListener; import android.view.MotionEvent; import android.view.GestureDetector; import android.util.Log; Stałe klasy { publiczny końcowy ciąg statyczny APP_TAG = "mytag"; } – FuzzyAmi

2

kilka komentuje

  1. musiałem podkręcić mój kod w następujący sposób:

    v.setOnTouchListener(new View.OnTouchListener() { 
        @Override   
        public boolean onTouch(View v, MotionEvent event) { 
    
         // return gesture.onTouchEvent(event); 
    
         gesture.onTouchEvent(event); 
         return true; // <-- this line made the difference 
        } 
    }); 
    
  2. Ponadto, jeśli używają pliku xml do utworzenia widoku

    View v = inflater.inflate(R.layout.my_view, null, false); 
    

Upewnij się, że faktycznie naciskasz odpowiedni widok. Dobrym sposobem na wyolbrzymienie testu jest uczynienie zarówno szerokości, jak i wysokości wartości "match_parent" zamiast "wrap_content" w pliku xml układu.

+0

Brakowało mi tego @mwillbanks nadpisuje onDown, aby zwrócić wartość true dla SimpleOnGestureListener. Zaimplementowałem tylko na onSingleTapConfirmed i onDoubleTap. – gnemnk

Powiązane problemy