mirror of
https://github.com/samsonjs/media.git
synced 2026-03-28 09:55:48 +00:00
Fix controller ui toggling when using SphericalSurfaceView
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=209909845
This commit is contained in:
parent
74e2384fb6
commit
3f70454cc2
4 changed files with 115 additions and 38 deletions
|
|
@ -59,6 +59,7 @@ import com.google.android.exoplayer2.text.TextOutput;
|
|||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||
import com.google.android.exoplayer2.ui.spherical.SingleTapListener;
|
||||
import com.google.android.exoplayer2.ui.spherical.SphericalSurfaceView;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
||||
|
|
@ -390,6 +391,7 @@ public class PlayerView extends FrameLayout {
|
|||
Assertions.checkState(Util.SDK_INT >= 15);
|
||||
SphericalSurfaceView sphericalSurfaceView = new SphericalSurfaceView(context);
|
||||
sphericalSurfaceView.setSurfaceListener(componentListener);
|
||||
sphericalSurfaceView.setSingleTapListener(componentListener);
|
||||
surfaceView = sphericalSurfaceView;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1021,15 +1023,10 @@ public class PlayerView extends FrameLayout {
|
|||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (!useController || player == null || ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
|
||||
if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
}
|
||||
if (!controller.isVisible()) {
|
||||
maybeShowController(true);
|
||||
} else if (controllerHideOnTouch) {
|
||||
controller.hide();
|
||||
}
|
||||
return true;
|
||||
return toggleControllerVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1067,6 +1064,18 @@ public class PlayerView extends FrameLayout {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean toggleControllerVisibility() {
|
||||
if (!useController || player == null) {
|
||||
return false;
|
||||
}
|
||||
if (!controller.isVisible()) {
|
||||
maybeShowController(true);
|
||||
} else if (controllerHideOnTouch) {
|
||||
controller.hide();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Shows the playback controls, but only if forced or shown indefinitely. */
|
||||
private void maybeShowController(boolean isForced) {
|
||||
if (isPlayingAd() && controllerHideDuringAds) {
|
||||
|
|
@ -1286,7 +1295,8 @@ public class PlayerView extends FrameLayout {
|
|||
TextOutput,
|
||||
VideoListener,
|
||||
OnLayoutChangeListener,
|
||||
SphericalSurfaceView.SurfaceListener {
|
||||
SphericalSurfaceView.SurfaceListener,
|
||||
SingleTapListener {
|
||||
|
||||
// TextOutput implementation
|
||||
|
||||
|
|
@ -1391,5 +1401,12 @@ public class PlayerView extends FrameLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SingleTapListener implementation
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
return toggleControllerVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui.spherical;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/** Listens tap events on a {@link android.view.View}. */
|
||||
public interface SingleTapListener {
|
||||
/**
|
||||
* Notified when a tap occurs with the up {@link MotionEvent} that triggered it.
|
||||
*
|
||||
* @param e The up motion event that completed the first tap.
|
||||
* @return Whether the event is consumed.
|
||||
*/
|
||||
boolean onSingleTapUp(MotionEvent e);
|
||||
}
|
||||
|
|
@ -91,6 +91,7 @@ public final class SphericalSurfaceView extends GLSurfaceView
|
|||
private final PhoneOrientationListener phoneOrientationListener;
|
||||
private final Renderer renderer;
|
||||
private final Handler mainHandler;
|
||||
private final TouchTracker touchTracker;
|
||||
private @Nullable SurfaceListener surfaceListener;
|
||||
private @Nullable SurfaceTexture surfaceTexture;
|
||||
private @Nullable Surface surface;
|
||||
|
|
@ -121,7 +122,7 @@ public final class SphericalSurfaceView extends GLSurfaceView
|
|||
|
||||
renderer = new Renderer();
|
||||
|
||||
TouchTracker touchTracker = new TouchTracker(renderer, PX_PER_DEGREES);
|
||||
touchTracker = new TouchTracker(context, renderer, PX_PER_DEGREES);
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = Assertions.checkNotNull(windowManager).getDefaultDisplay();
|
||||
phoneOrientationListener = new PhoneOrientationListener(display, touchTracker, renderer);
|
||||
|
|
@ -155,6 +156,11 @@ public final class SphericalSurfaceView extends GLSurfaceView
|
|||
surfaceListener = listener;
|
||||
}
|
||||
|
||||
/** Sets the {@link SingleTapListener} used to listen to single tap events on this view. */
|
||||
public void setSingleTapListener(@Nullable SingleTapListener listener) {
|
||||
touchTracker.setSingleTapListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoFrameAboutToBeRendered(
|
||||
long presentationTimeUs, long releaseTimeNs, Format format) {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,11 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.ui.spherical;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.BinderThread;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
|
|
@ -42,7 +45,8 @@ import android.view.View;
|
|||
* Mesh as the user moves their finger. However, that requires quaternion interpolation.
|
||||
*/
|
||||
// @VisibleForTesting
|
||||
/*package*/ class TouchTracker implements View.OnTouchListener {
|
||||
/*package*/ class TouchTracker extends GestureDetector.SimpleOnGestureListener
|
||||
implements View.OnTouchListener {
|
||||
|
||||
/*package*/ interface Listener {
|
||||
void onScrollChange(PointF scrollOffsetDegrees);
|
||||
|
|
@ -58,16 +62,27 @@ import android.view.View;
|
|||
|
||||
private final Listener listener;
|
||||
private final float pxPerDegrees;
|
||||
private final GestureDetector gestureDetector;
|
||||
// The conversion from touch to yaw & pitch requires compensating for device roll. This is set
|
||||
// on the sensor thread and read on the UI thread.
|
||||
private volatile float roll;
|
||||
private @Nullable SingleTapListener singleTapListener;
|
||||
|
||||
public TouchTracker(Listener listener, float pxPerDegrees) {
|
||||
@SuppressWarnings({
|
||||
"nullness:assignment.type.incompatible",
|
||||
"nullness:argument.type.incompatible"
|
||||
})
|
||||
public TouchTracker(Context context, Listener listener, float pxPerDegrees) {
|
||||
this.listener = listener;
|
||||
this.pxPerDegrees = pxPerDegrees;
|
||||
gestureDetector = new GestureDetector(context, this);
|
||||
roll = SphericalSurfaceView.UPRIGHT_ROLL;
|
||||
}
|
||||
|
||||
public void setSingleTapListener(@Nullable SingleTapListener listener) {
|
||||
singleTapListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts ACTION_MOVE events to pitch & yaw events while compensating for device roll.
|
||||
*
|
||||
|
|
@ -75,36 +90,46 @@ import android.view.View;
|
|||
*/
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// Initialize drag gesture.
|
||||
previousTouchPointPx.set(event.getX(), event.getY());
|
||||
return true;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
// Calculate the touch delta in screen space.
|
||||
float touchX = (event.getX() - previousTouchPointPx.x) / pxPerDegrees;
|
||||
float touchY = (event.getY() - previousTouchPointPx.y) / pxPerDegrees;
|
||||
previousTouchPointPx.set(event.getX(), event.getY());
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
float r = roll; // Copy volatile state.
|
||||
float cr = (float) Math.cos(r);
|
||||
float sr = (float) Math.sin(r);
|
||||
// To convert from screen space to the 3D space, we need to adjust the drag vector based
|
||||
// on the roll of the phone. This is standard rotationMatrix(roll) * vector math but has
|
||||
// an inverted y-axis due to the screen-space coordinates vs GL coordinates.
|
||||
// Handle yaw.
|
||||
accumulatedTouchOffsetDegrees.x -= cr * touchX - sr * touchY;
|
||||
// Handle pitch and limit it to 45 degrees.
|
||||
accumulatedTouchOffsetDegrees.y += sr * touchX + cr * touchY;
|
||||
accumulatedTouchOffsetDegrees.y =
|
||||
Math.max(
|
||||
-MAX_PITCH_DEGREES, Math.min(MAX_PITCH_DEGREES, accumulatedTouchOffsetDegrees.y));
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
// Initialize drag gesture.
|
||||
previousTouchPointPx.set(e.getX(), e.getY());
|
||||
return true;
|
||||
}
|
||||
|
||||
listener.onScrollChange(accumulatedTouchOffsetDegrees);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
// Calculate the touch delta in screen space.
|
||||
float touchX = (e2.getX() - previousTouchPointPx.x) / pxPerDegrees;
|
||||
float touchY = (e2.getY() - previousTouchPointPx.y) / pxPerDegrees;
|
||||
previousTouchPointPx.set(e2.getX(), e2.getY());
|
||||
|
||||
float r = roll; // Copy volatile state.
|
||||
float cr = (float) Math.cos(r);
|
||||
float sr = (float) Math.sin(r);
|
||||
// To convert from screen space to the 3D space, we need to adjust the drag vector based
|
||||
// on the roll of the phone. This is standard rotationMatrix(roll) * vector math but has
|
||||
// an inverted y-axis due to the screen-space coordinates vs GL coordinates.
|
||||
// Handle yaw.
|
||||
accumulatedTouchOffsetDegrees.x -= cr * touchX - sr * touchY;
|
||||
// Handle pitch and limit it to 45 degrees.
|
||||
accumulatedTouchOffsetDegrees.y += sr * touchX + cr * touchY;
|
||||
accumulatedTouchOffsetDegrees.y =
|
||||
Math.max(-MAX_PITCH_DEGREES, Math.min(MAX_PITCH_DEGREES, accumulatedTouchOffsetDegrees.y));
|
||||
|
||||
listener.onScrollChange(accumulatedTouchOffsetDegrees);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
if (singleTapListener != null) {
|
||||
return singleTapListener.onSingleTapUp(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
|
|
|
|||
Loading…
Reference in a new issue