Search code examples
androidfragmentandroid-videoviewgesturedetection

Android gesture detector in videoView inside fragment


I have a videoView in a fragment and i need to detect gestures on it. I tried with the following code with no success. How can i achieve this correctly? Need help please. Thanks in advance.

CustomVideoView.java

public class CustomVideoView extends VideoView {

private GestureDetector gestureDetector;


public CustomVideoView(Context context) {
    super(context);
}


public CustomVideoView(Context context, AttributeSet attrs) {
    super(context, attrs);
}


public CustomVideoView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}


@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
}


@Override
public boolean onTouchEvent(MotionEvent ev) {
    return gestureDetector.onTouchEvent(ev) || super.onTouchEvent(ev);
}

public void setGestureDetector(GestureDetector gestureDetector) {
    this.gestureDetector = gestureDetector;
}
}

MyFragment.java

public class MyFragment extends Fragment{

private Context context;
private CustomVideoView videoView;


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

    context = getActivity();

    View tmp_view = inflater.inflate(R.layout.my_fragment, container, false);
    assert tmp_view != null;

    videoView = (CustomVideoView) tmp_view.findViewById(R.id.videoView);

    MediaController mc = new MediaController(context);
    mc.setAnchorView(videoView);
    mc.setMediaPlayer(videoView);

    Uri video = Uri.parse("myUrl");
    videoView.setMediaController(mc);
    videoView.setVideoURI(video);
    videoView.requestFocus();
    videoView.start();

    videoView.setGestureDetector(new GestureDetector(new CustomeGestureDetector()));

    return tmp_view;

}

private class CustomeGestureDetector extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        //NEVER CALLED
        if(e1 == null || e2 == null) return false;
        if(e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return false;
        else {
            try { // right to left swipe .. go to next page
                if(e1.getX() - e2.getX() > 100 && Math.abs(velocityX) > 800) {
                    //do your stuff

                    Log.i("MyApp", "right to left");
                    return true;
                } //left to right swipe .. go to prev page
                else if (e2.getX() - e1.getX() > 100 && Math.abs(velocityX) > 800) {
                    //do your stuff

                    Log.i("MyApp", "left to right");
                    return true;
                } //bottom to top, go to next document
                else if(e1.getY() - e2.getY() > 100 && Math.abs(velocityY) > 800
                        && videoView.getScrollY() >=  videoView.getHeight()) {
                    //do your stuff
                    return true;
                } //top to bottom, go to prev document
                else if (e2.getY() - e1.getY() > 100 && Math.abs(velocityY) > 800 ) {
                    //do your stuff
                    return true;
                }
            } catch (Exception e) { // nothing
            }
            return false;
        }
    }

    @Override
    public boolean onDown(MotionEvent event) {
        Log.i("MyApp", "onDown");
        //THIS IS CALLED WHEN TOUCH
        return super.onDown(event);
    }

}

When i touch my VideView only respond its controls (play, pause...), but the gesture detector never called. Maybe these controls are disturbing my gesture detector??

The onDown event is called when touch but never the onFling. Is it possible to achieve the onFling function with the onDown event?


Solution

  • I dont know why but adding the onDown method to my CustomeGestureDetector makes onFling method get called.

    private class CustomeGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    
        if(e1 == null || e2 == null) return false;
        if(e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return false;
        else {
            try { // right to left swipe .. go to next page
                if(e1.getX() - e2.getX() > 100 && Math.abs(velocityX) > 800) {
                    //do your stuff
    
                    Log.i("MyApp", "right to left");
                    return true;
                } //left to right swipe .. go to prev page
                else if (e2.getX() - e1.getX() > 100 && Math.abs(velocityX) > 800) {
                    //do your stuff
    
                    Log.i("MyApp", "left to right");
                    return true;
                } //bottom to top, go to next document
                else if(e1.getY() - e2.getY() > 100 && Math.abs(velocityY) > 800
                        && videoView.getScrollY() >=  videoView.getHeight()) {
                    //do your stuff
                    return true;
                } //top to bottom, go to prev document
                else if (e2.getY() - e1.getY() > 100 && Math.abs(velocityY) > 800 ) {
                    //do your stuff
                    return true;
                }
            } catch (Exception e) { // nothing
            }
    
            return false;
            }
        }
    
       @Override
        public boolean onDown(MotionEvent event) {
              return true;
        }
    
    }