2013-06-30 12 views
9

Ok. To coś doprowadza mnie do szału.OnFling MotionEvent e1 null?

Kilka dni temu mogłem zaimplementować poniższy kod i toast zadzwonił z powodzeniem, gdy próbowałem przesuwać palcem w prawo lub w lewo.

Jednak teraz nie można go nazwać, ponieważ e1 ma zawsze wartość zerową!

Jak to się mogło stać? Próbuję tego kodu na emulatorze, ale użytkownik zgłasza mi, że nie działa również na prawdziwym urządzeniu.

public class SwipeGestureListener extends GestureDetector.SimpleOnGestureListener{ 

    private static final int SWIPE_MIN_DISTANCE = 150; 
    private static final int SWIPE_MAX_OFF_PATH = 100; 

    private static final int SWIPE_THRESHOLD_VELOCITY = 100; 
    private final Activity activity; 
    protected MotionEvent mLastOnDownEvent = null; 

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

    @Override 
    public boolean onDown(MotionEvent e) { 
     mLastOnDownEvent = e; 
     System.out.println(e); 
     return super.onDown(e); 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     System.out.println(e1 + " " + e2); 
     if (e1==null) 
      e1 = mLastOnDownEvent; 
     if (e1==null || e2==null) 
      return false; 

     float dX = e2.getX()-e1.getX(); 
     float dY = e2.getY()-e1.getY(); 

     if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE) { 

      if (dX>0) { 
       Toast.makeText(activity.getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show(); 
       activity.fetchPrevious(); 
      } else { 
       Toast.makeText(activity.getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show(); 
       activity.fetchNext(); 
      } 

      return true; 
     } 

     return false; 
    } 

} 

kod realizacji gest:

final GestureDetector gdt = new GestureDetector(this, new SwipeGestureListener(this)); 
listview.setOnTouchListener(new OnTouchListener(){ 

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

}); 
+0

może ktoś podać prawidłowe rozwiązanie tego jestem też w obliczu tego samego problemu?. – Gibs

Odpowiedz

1

Próbowałem swój kod i rzeczywiście nie działa, potem zmienił GestureDetector do nowszego/Aktualizacja API „GestureDetectorCompat” i się zmienił kilka innych rzeczy: Użył GestureDetector.OnGestureListener zamiast OnSimpleGestureListener, onDown() powinien zwrócić wartość true, a następnie zadziałało. Nie mogę ci tego wyjaśnić, jaki był dokładny problem. Ale linie zmiany wydawały się problematyczne. Może ktoś może wyjaśnić podstawowy problem. Zajrzyj do kodu, który działa:

public class MainActivity extends Activity { 
    ImageView imageView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     imageView= (ImageView) findViewById(R.id.imageView1); 

     final GestureDetectorCompat gdt = new GestureDetectorCompat(this, new SwipeGestureListener(this)); 
     imageView.setOnTouchListener(new OnTouchListener(){ 

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

     }); 

    } 




    public class SwipeGestureListener implements GestureDetector.OnGestureListener{ 

     private static final int SWIPE_MIN_DISTANCE = 150; 
     private static final int SWIPE_MAX_OFF_PATH = 100; 

     private static final int SWIPE_THRESHOLD_VELOCITY = 100; 
     private final Activity activity; 
     protected MotionEvent mLastOnDownEvent = null; 

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

     @Override 
     public boolean onDown(MotionEvent e) { 
      mLastOnDownEvent = e; 
      System.err.println("ondown"); 
      //System.out.println(e); 
      return true; 
     } 

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      System.err.println("onFling"); 
      System.out.println(e1 + " " + e2); 
      if (e1==null) 
       e1 = mLastOnDownEvent; 
      if (e1==null || e2==null) 
       return false; 

      float dX = e2.getX()-e1.getX(); 
      float dY = e2.getY()-e1.getY(); 

      if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE) { 

       if (dX>0) { 
        Toast.makeText(activity.getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show(); 
        // activity.fetchPrevious(); 
       } else { 
        Toast.makeText(activity.getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show(); 
        // activity.fetchNext(); 
       } 

       return true; 
      } 

      return false; 
     } 

     @Override 
     public void onLongPress(MotionEvent e) { 
      // TODO Auto-generated method stub 

    } 

     @Override 
     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
      // TODO Auto-generated method stub 
      return false; 
    } 

     @Override 
     public void onShowPress(MotionEvent e) { 
      // TODO Auto-generated method stub 

    } 

     @Override 
     public boolean onSingleTapUp(MotionEvent e) { 
      // TODO Auto-generated method stub 
      return false; 
     } 

     } 

    } 

Proszę spróbować!

+0

Przepraszam G_J, wciąż jest taka sama. e1 nadal daje mi zerową wartość – Rendy

+0

To naprawdę dziwne. Czy próbowałeś tego z innym View (nie ListView)? Powyższy kod działa bezbłędnie, gdy rejestruję ImageView w OnTouchListener! Czy mógłbyś pokazać resztę swojego kodu? –

+0

Tak, zgadzam się .. Działa z innym widokiem, ale nie na jednym z moich listview. Postaram się zbadać xml. Dzięki za pomoc G_J – Rendy

0

Miałem ten sam problem. Upewnij się, że wszystkie widoki dodają tę samą metodę setOnTouchListener(). Jeśli twoje miejsce dotyku jest poza widokiem, dostaniesz null na e1.

moim przykładzie:

private View.OnTouchListener onTouchListener = new OnSwipeTouchListener(mActivity) { 

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

     @Override 
     public void onSwipeLeft() { 

     } 

     @Override 
     public void onSwipeRight() { 
     } 
    }; 


    @Override 
    public View onCreateView(LayoutInflater inflater, 
         ViewGroup container, Bundle savedInstanceState) { 

    //Inflate the layout for this fragment 
    View v = inflater.inflate(R.layout.view, container, false); 
    mListView = (ListView) v.findViewById(R.id.list); 
    v.setFocusableInTouchMode(true); 
    v.requestFocus(); 
    v.setOnTouchListener(onTouchListener); 
    mListView.setOnTouchListener(onTouchListener); 

    mAdapter = new OnlineAdapter(getActivity(), R.layout.row, onTouchListener); 
    mListView.setAdapter(mAdapter); 
    return v; 

} 

A moja lista adapter:

@Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 

     // something 

      mImage = (ImageView) convertView.findViewById(R.id.image); 
      mImage.setOnTouchListener(onTouchListener); 
    } 
0

miałem ten sam problem. Jeśli na liście znajduje się katalog onclicklistener, który przesuwa elementy, powinieneś usunąć te detektory. Wtedy to zadziała. Dziękuję ..

0

miałem podobny problem i rozwiązać go dodając FrameLayout wraz z potrzebnych View (używałem GridView, ale że może pracować z ListView lub innego widzenia)

GestureListener jest taki jak twoje. Układ:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:id="@+id/colors_grid_panel" 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="@color/white" 
      android:paddingLeft="@dimen/create_side_padding" 
      android:paddingRight="@dimen/create_side_padding" 
      android:visibility="gone"> 

    <GridView 
     android:id="@+id/colors_grid" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:numColumns="7" 
     android:paddingBottom="10dp" 
     android:paddingTop="10dp" 
     android:stretchMode="columnWidth" 
     android:verticalSpacing="10dp"/> 

    <FrameLayout 
     android:id="@+id/stub" 
     android:focusable="false" 
     android:focusableInTouchMode="false" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

</FrameLayout> 

W kodzie:

colorsGrid.setOnTouchListener(onSwipeTouchListener); 
stub.setOnTouchListener(onSwipeTouchListener); 
Powiązane problemy