102 lines
3.3 KiB
Java
102 lines
3.3 KiB
Java
|
package org.schabi.newpipe.views;
|
||
|
|
||
|
import android.content.Context;
|
||
|
import android.util.AttributeSet;
|
||
|
import android.view.SurfaceView;
|
||
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
||
|
|
||
|
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.*;
|
||
|
|
||
|
public class ExpandableSurfaceView extends SurfaceView {
|
||
|
private int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
||
|
private int baseHeight = 0;
|
||
|
private int maxHeight = 0;
|
||
|
private float videoAspectRatio = 0f;
|
||
|
private float scaleX = 1.0f;
|
||
|
private float scaleY = 1.0f;
|
||
|
|
||
|
public ExpandableSurfaceView(Context context, AttributeSet attrs) {
|
||
|
super(context, attrs);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||
|
if (videoAspectRatio == 0f) return;
|
||
|
|
||
|
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||
|
boolean verticalVideo = videoAspectRatio < 1;
|
||
|
// Use maxHeight only on non-fit resize mode and in vertical videos
|
||
|
int height = maxHeight != 0 && resizeMode != AspectRatioFrameLayout.RESIZE_MODE_FIT && verticalVideo ? maxHeight : baseHeight;
|
||
|
|
||
|
if (height == 0) return;
|
||
|
|
||
|
float viewAspectRatio = width / ((float) height);
|
||
|
float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
|
||
|
scaleX = 1.0f;
|
||
|
scaleY = 1.0f;
|
||
|
|
||
|
switch (resizeMode) {
|
||
|
case AspectRatioFrameLayout.RESIZE_MODE_FIT:
|
||
|
if (aspectDeformation > 0) {
|
||
|
height = (int) (width / videoAspectRatio);
|
||
|
} else {
|
||
|
width = (int) (height * videoAspectRatio);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case RESIZE_MODE_ZOOM:
|
||
|
if (aspectDeformation < 0) {
|
||
|
scaleY = viewAspectRatio / videoAspectRatio;
|
||
|
} else {
|
||
|
scaleX = videoAspectRatio / viewAspectRatio;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
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(boolean changed, int left, int top, int right, 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(int base, int max) {
|
||
|
if (baseHeight == base && maxHeight == max) return;
|
||
|
baseHeight = base;
|
||
|
maxHeight = max;
|
||
|
requestLayout();
|
||
|
}
|
||
|
|
||
|
@AspectRatioFrameLayout.ResizeMode
|
||
|
public void setResizeMode(int newResizeMode) {
|
||
|
if (resizeMode == newResizeMode) return;
|
||
|
|
||
|
resizeMode = newResizeMode;
|
||
|
requestLayout();
|
||
|
}
|
||
|
|
||
|
@AspectRatioFrameLayout.ResizeMode
|
||
|
public int getResizeMode() {
|
||
|
return resizeMode;
|
||
|
}
|
||
|
|
||
|
public void setAspectRatio(float aspectRatio) {
|
||
|
if (videoAspectRatio == aspectRatio) return;
|
||
|
|
||
|
videoAspectRatio = aspectRatio;
|
||
|
requestLayout();
|
||
|
}
|
||
|
}
|