Search code examples
javaandroidxmllistviewgesturedetector

How to use Gesture Detector over a ListView in Android App


I have a gesture detector used to scroll between "pages." Each page will consist of a listview. The problem I am having is that my swipes aren't being picked up over the ListView. They work above and below the ListView, just not over it, as displayed in the picture below. Does anyone have any idea how to make the swipe work OVER the ListView? Thanks!

App Capture

Here is my Activity:

public class MainActivity extends ActionBarActivity {

ListView listView;

TextView test;
ArrayList<Location> arrayOfLocations;
LocationAdapter adapter;
// public static Bitmap bitmap;
Button refresh;
// ProgressBar progress;
ImageView view;

private GestureDetector gestureDetector;

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

    setContentView(R.layout.activity_main);

    listView = (ListView) findViewById(R.id.listView1);

    // test = (TextView) findViewById(R.id.textView2);
    // Construct the data source
    arrayOfLocations = new ArrayList<Location>();

    // Create the adapter to convert the array to views
    adapter = new LocationAdapter(this, arrayOfLocations);
    adapter.add(new Location(null, "Title", "Test", "Test2","Test3"));
    listView.setAdapter(adapter);

    gestureDetector = new GestureDetector(this, new SwipeGestureDetector());

}

 @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (gestureDetector.onTouchEvent(event)) {
      return true;
    }
    return super.onTouchEvent(event);
  }

  private void onLeftSwipe() {
        Toast.makeText(getApplicationContext(), "Swipe!",
                Toast.LENGTH_LONG).show();
  }

  private void onRightSwipe() {
        Toast.makeText(getApplicationContext(), "Swipe!",
                Toast.LENGTH_LONG).show();
  }

  // Private class for gestures
  private class SwipeGestureDetector 
          extends SimpleOnGestureListener {
    // Swipe properties, you can change it to make the swipe 
    // longer or shorter and speed
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 200;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2,
                         float velocityX, float velocityY) {
      try {
        float diffAbs = Math.abs(e1.getY() - e2.getY());
        float diff = e1.getX() - e2.getX();

        if (diffAbs > SWIPE_MAX_OFF_PATH)
          return false;

        // Left swipe
        if (diff > SWIPE_MIN_DISTANCE
        && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
           MainActivity.this.onLeftSwipe();

        // Right swipe
        } else if (-diff > SWIPE_MIN_DISTANCE
        && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          MainActivity.this.onRightSwipe();
        }
      } catch (Exception e) {
        Log.e("YourActivity", "Error on gestures");
      }
      return false;
    }
  }


}

and here is my layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="vertical" >

<ProgressBar
    android:id="@+id/progressbar_loading"
    style="?android:attr/progressBarStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone" >
</ProgressBar>

<TextView
    android:id="@+id/textView1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#CCCCCC"
    android:padding="10dip"
    android:text="Stands Near You"
    android:textSize="30dip" />

<Button
    android:id="@+id/refresh"
    android:layout_width="wrap_content"
    android:layout_height="26dp"
    android:layout_marginLeft="250dip"
    android:layout_marginTop="-40dip"
    android:background="#FFFFFF"
    android:text="Refresh"
    android:textSize="9sp" />

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="fill_parent"
    android:layout_height="20dip"
    android:src="@drawable/abc_ab_bottom_transparent_dark_holo" />

<ListView
    android:id="@+id/listView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginTop="15dp"
    android:dividerHeight="10.0sp" >
</ListView>

</LinearLayout>

Solution

  • Try implementing onInterceptTouchEvent(MotionEvent event) and passing whatever functionality you need to onTouchEvent. Source.