NewPipe/app/src/main/java/org/schabi/newpipe/views/ExpandableSurfaceView.java

114 lines
3.7 KiB
Java

package org.schabi.newpipe.views;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.SurfaceView;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_FIT;
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
public class ExpandableSurfaceView extends SurfaceView {
private int resizeMode = RESIZE_MODE_FIT;
private int baseHeight = 0;
private int maxHeight = 0;
private float videoAspectRatio = 0.0f;
private float scaleX = 1.0f;
private float scaleY = 1.0f;
public ExpandableSurfaceView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (videoAspectRatio == 0.0f) {
return;
}
int width = MeasureSpec.getSize(widthMeasureSpec);
final boolean verticalVideo = videoAspectRatio < 1;
// Use maxHeight only on non-fit resize mode and in vertical videos
int height = maxHeight != 0
&& resizeMode != RESIZE_MODE_FIT
&& verticalVideo ? maxHeight : baseHeight;
if (height == 0) {
return;
}
final float viewAspectRatio = width / ((float) height);
final float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
scaleX = 1.0f;
scaleY = 1.0f;
if (resizeMode == RESIZE_MODE_FIT
// KitKat doesn't work well when a view has a scale like needed for ZOOM
|| (resizeMode == RESIZE_MODE_ZOOM
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)) {
if (aspectDeformation > 0) {
height = (int) (width / videoAspectRatio);
} else {
width = (int) (height * videoAspectRatio);
}
} else if (resizeMode == RESIZE_MODE_ZOOM) {
if (aspectDeformation < 0) {
scaleY = viewAspectRatio / videoAspectRatio;
} else {
scaleX = videoAspectRatio / viewAspectRatio;
}
}
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
/**
* Scale view only in {@link #onLayout} to make transition for ZOOM mode as smooth as possible.
*/
@Override
protected void onLayout(final boolean changed,
final int left, final int top, final int right, final int bottom) {
setScaleX(scaleX);
setScaleY(scaleY);
}
/**
* @param base The height that will be used in every resize mode as a minimum height
* @param max The max height for vertical videos in non-FIT resize modes
*/
public void setHeights(final int base, final int max) {
if (baseHeight == base && maxHeight == max) {
return;
}
baseHeight = base;
maxHeight = max;
requestLayout();
}
public void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int newResizeMode) {
if (resizeMode == newResizeMode) {
return;
}
resizeMode = newResizeMode;
requestLayout();
}
@AspectRatioFrameLayout.ResizeMode
public int getResizeMode() {
return resizeMode;
}
public void setAspectRatio(final float aspectRatio) {
if (videoAspectRatio == aspectRatio) {
return;
}
videoAspectRatio = aspectRatio;
requestLayout();
}
}