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