Monday, July 30, 2018

android - Fling gesture detection on grid layout



I want to get fling gesture detection working in my Android application.




What I have is a GridLayout that contains 9 ImageViews. The source can be found here: Romain Guys's Grid Layout.



That file I take is from Romain Guy's Photostream application and has only been slightly adapted.



For the simple click situation I need only set the onClickListener for each ImageView I add to be the main activity which implements View.OnClickListener. It seems infinitely more complicated to implement something that recognizes a fling. I presume this is because it may span views?




  • If my activity implements
    OnGestureListener I don't know how to
    set that as the gesture listener for

    the Grid or the Image views that I
    add.



    public class SelectFilterActivity extends Activity implements
    View.OnClickListener, OnGestureListener { ...

  • If my activity implements
    OnTouchListener then I have no
    onFling method to override (it has
    two events as parameters allowing me

    to determine if the fling was
    noteworthy).



    public class SelectFilterActivity extends Activity implements
    View.OnClickListener, OnTouchListener { ...

  • If I make a custom View, like GestureImageView that extends ImageView I don't know how to tell the activity that a fling has occurred from the view. In any case, I tried this and the methods weren't called when I touched the screen.




I really just need a concrete example of this working across views. What, when and how should I attach this listener? I need to be able to detect single clicks also.




// 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;
}
}
});



Is it possible to lay a transparent view over the top of my screen to capture flings?



If I choose not to inflate my child image views from XML can I pass the GestureDetector as a constructor parameter to a new subclass of ImageView that I create?



This is the very simple activity that I'm trying to get the fling detection to work for: SelectFilterActivity (Adapted from photostream).



I've been looking at these sources:






Nothing has worked for me so far and I was hoping for some pointers.


Answer



Thanks to Code Shogun, whose code I adapted to my situation.



Let your activity implementOnClickListener as usual:



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;
}
}
}


Attach your gesture listener to all the views you add to the main layout;




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


Watch in awe as your overridden methods are hit, both the onClick(View v) of the activity and the onFling of the gesture listener.



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

}


The post 'fling' dance is optional but encouraged.


No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...