user3065901
user3065901

Reputation: 4778

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?

Upvotes: 0

Views: 1288

Answers (2)

user3065901
user3065901

Reputation: 4778

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

}

Upvotes: 1

Siddharth2092
Siddharth2092

Reputation: 407

For using GestureDetector in a simple way in android create a listener class which extends SimpleOnGestureListner and then override the onScroll and onFling methods. I think those shall be the only gestures that a user could come across on the video apart from onTouch.

Sample Source Code:

class VideoGestureDetector extends SimpleOnGestureListener {

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

      // implementation when the user scrolls
      return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

      // implementation when the user flings
      return false;
    }
  }

Upvotes: 0

Related Questions