javaandroidmediacontrollerexoplayer

Exoplayer hide PlaybackControlView onClick (not onTouch)


I am developing a custom UI on top of ExoPlayer, and I noticed that the controls (PlaybackControlView) hide when I touch the screen, not when I click.

I wanted to change to a click and checked how I can change the event listener, but so far could not find an easy solution. I checked the source SimpleExoPlayerView.java and I noticed that it actually is hardcoded:

  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    if (!useController || player == null || ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
      return false;
    }
    if (controller.isVisible()) {
      controller.hide();
    } else {
      maybeShowController(true);
    }
    return true;
  }

So far I could think of two solutions. One is to change the ExoPlayer's source code, but I do not like it since I will have to make modifications every time I update the ExoPlayer.

The second solution I could think of is simply to try to handle it myself, for example, to add my own listeners, and show and hide the controls myself. I have not tried this yet, but it seems possible.

Is there another better solution, like overriding the listeners, etc?

Update: I am using custom UI by inflating exo_playback_control_view.xml


Solution

  • By looking at this answer you can see that an OnTouchListener#onTouch is called BEFORE the View#onTouchEvent so you can set an OnTouchListener to the view, consume the MotionEvent and it will not be passed onto the onTouchEvent method.

    For example, using this code only "onTouch: LISTENER!!!" is logged when touching the view, and not "onTouchEvent: onTouchEvent!!!":

    EDIT - to add your request for a click event handling I added the use of GestureDetector, using this answer - so now upon click "onSingleTapUp: TAP DETECTED" is logged as well.

    public class TouchingView extends View {
    
        private final static String TAG="TouchingView";
    
        private OnTouchListener touchListener;
        private GestureDetector gestureDetector;
    
        public TouchingView(Context context) {
            super(context);
            touchListener = new TouchListener();
            gestureDetector = new GestureDetector(getContext(), 
                             (GestureDetector.OnGestureListener) touchListener);
            setOnTouchListener(touchListener);
        }
    
        public TouchingView(Context context, AttributeSet attrs) {
            super(context, attrs);
            touchListener = new TouchListener();
            gestureDetector = new GestureDetector(getContext(), 
                             (GestureDetector.OnGestureListener) touchListener);
            setOnTouchListener(touchListener);
        }
    
        public TouchingView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            touchListener = new TouchListener();
            gestureDetector = new GestureDetector(getContext(), 
                             (GestureDetector.OnGestureListener) touchListener);
            setOnTouchListener(touchListener);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            Log.d(TAG, "onTouchEvent: onTouchEvent!!!"); //not logged
            return super.onTouchEvent(event);
        }
    
        private class TouchListener extends GestureDetector.SimpleOnGestureListener 
                                    implements View.OnTouchListener{
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.d(TAG, "onTouch: LISTENER!!!"); //logged upon every touch event. twice upon click (for UP and for DOWN)
                gestureDetector.onTouchEvent(event);
                return true; //preventing the view's onTouchEvent from firing
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) { //you can override onSingleTapConfirmed if you don't want doubleClick to fire it
                Log.d(TAG, "onSingleTapUp: TAP DETECTED"); //logged only upon click
                return true;
            }
        }
    }